I'm writing a script (package method) to read XML documents per the GraphML schema. I'm using XML::LibXML for the first time and need help understanding XPath queries with documents that use namespaces. See GraphML Primer

The GraphML schema includes a namespace attribute without a prefix as follows.

<graphml xmlns="http://graphml.graphdrawing.org/xmlns" [more gorp] >

Recursively traversing the document tree using the "nonBlankChildNodes" method works fine. But from any node/element in the traversal, the findNodes method (called from the retrieved node/element) with an XPath query doesn't work (never returns any found nodes). I assume this is a namespace issue?

Alternatively, creating an XPathContext object and then registering the namespace (defining a prefix) does enable the use of the findNodes method but only using that $xpc object as follows.

my $xpc = XML::LibXML::XPathContext->new($dom); $xpc->registerNs('gml', 'http://graphml.graphdrawing.org/xmlns'); if (my $graphNode = @{$xpc->findnodes('/gml:graphml/gml:graph')}[0] ) +{ if ($graphNode->hasAttributes()) { my $directed = $graphNode->getAttribute('edgedefault') || ''; print "edgedefault = '$directed'\n"; } } else { print "did not find graph node edgedefault value\n"; }

Once I get to a particular node (eg, an "edge" node that may contain a child "data" element), calling that node's findNodes method to find a specific child element using an XPath query doesn't work (never returns any matching nodes/elements). If I understand correctly, from a given node, it should be possible to find descendant nodes using an XPath query of the form ".//data" (where data is a node name).

The alternative that does work is to call the $xpc object's findNodes method adding the current (eg., edge) node as the context node as follows.

my $weightXPATH = ".//gml:data[\@key=\"$weightKey\"]"; if (my $dataWeightNode = @{$xpc->findnodes($weightXPATH,$edgeElement)} +[0]) { $weight = $dataWeightNode->textContent(); }

In essence, all calls to findNodes must be called from the original $xpc object optionally using a retrieved node as the context node. Am I missing something fundamental or doing something wrong? Or is this the correct use of XML::LibXML for documents with XML namespaces?

Many thanks for shared wisdom and guidance.


In reply to XML::LibXML with namespace with no prefix by dallen16

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.