Re: XML::LibXML XPath fails to find xmlns:xml="http://www.w3.org/XML/1998/namespace"

Petr Pajas <[email protected]>
Newsgroups gmane.comp.lang.perl.xml
Organization UFAL MFF UK
Message-ID <[email protected]>
Hi Emmanuel, 

you are right, but is it worth fixing? The namespace:: axis is problematic and 
not fully implemented even in libxml2 itself. The problem is that namespace 
nodes are in libxml2 represented by a very simple structure (compared to 
other nodes); unlike for instance ordinary attribute nodes, they do not know 
their owner element (e.g. namespace::*/parent::* won't work), sibling 
attributes, etc. Also their life cycle in libxml2 is different and quite 
complicated (a NS node can be attached to no element, yet still there may be 
elements refering to it as their namespace). For this reason, XML::LibXML's 
memory management is quite elementary for NS nodes compared to other nodes. 
We currently create a copy of xmlNs struct every time we expose a namespace 
to Perl. It is simple but safe.

What libxml2 does when it needs to instantiate a NS node for the 'xml' prefix 
is that it creates the xmlNs struct by hand (avoiding the xmlNewNs 
constructor):

        xmlNsPtr ns;
        ns = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
        if (ns == NULL) {
            xmlTreeErrMemory(
                "allocating the XML namespace");
            return (NULL);
        }
        memset(ns, 0, sizeof(xmlNs));
        ns->type = XML_LOCAL_NAMESPACE;
        ns->href = xmlStrdup(XML_XML_NAMESPACE);
        ns->prefix = xmlStrdup((const xmlChar *)"xml");

I could of course do the same, but I don't feel very comfortable adding such 
an unencapsulated code to XML::LibXML, but I'm willing to if you insist.

If you think you have a use case for which it is worth fixing, you can file a 
bug on rt.cpan.org and I'll take care of it while working on a next release.

Best,

-- Petr

On Monday 29 December 2008 10:58:27 Emmanuel Rodriguez wrote:
> Hi,
>
> I have found a strange behavior of XML::LibXML when handling the results
> of an XPath search that includes namespaces using the prefix 'xml'.
>
> If a document defines the following namespace:
> xmlns:xml="http://www.w3.org/XML/1998/namespace" then the XPath
> expression '//namespace::*' will not return that namespace. I have
> attached a test case that shows the problem. The test may seem strange
> as there are more namespaces returned than declared but this is what
> xmllint --shell returns!
>
> I think that this "bug" is a border line case as the prefix 'xml' is
> reserved in the XML specification. Although, I think that it should be
> fine to use xmlns:xml="http://www.w3.org/XML/1998/namespace" in a
> document [See http://www.stylusstudio.com/xmldev/200201/post91720.html].
>
> I tried to use xmllint --shell and a sample C program using the XPath
> API of libxml and they both work fine. So I made some investigation and
> found out that the XS method XML::LibXML::Node::_findnodes() is removing
> the nodes involuntarily through this code:
>
>   if (tnode->type == XML_NAMESPACE_DECL) {
>     xmlNsPtr newns = xmlCopyNamespace((xmlNsPtr)tnode);
>     if ( newns != NULL ) {
>       element = NEWSV(0,0);
>       cls = PmmNodeTypeName( tnode );
>       element = sv_setref_pv( element,
>         (const char *)cls,
>         newns
>       );
>     }
>     else {
>       continue;
>     }
>   }
>
> The call to xmlCopyNamespace() is the source of the problem.
> xmlCopyNamespace() uses xmlNewNs() to create a new node, but xmlNewNs()
> has the following assertion:
>
>   if ((prefix != NULL) && (xmlStrEqual(prefix, BAD_CAST "xml")))
>     return(NULL);
>
> That's why findnodes() is discarding some results, xmlNewNs() refuses to
> create a namespace node having the prefix "xml".
>
> PS: The same should be true for XML::LibXML::XPathContext::_findnodes().
>
> Emmanuel Rodriguez.


_______________________________________________
Perl-XML mailing list
[email protected]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.