I am terribly confused about how I am supposed to make XML::LibXML correctly use name spaces.

I am experimenting with CalDAV and I include two examples from RFC4918

# Example in section 9.1.3 of RFC4918 my $txt1 = '<?xml version="1.0" encoding="utf-8" ?> <D:propfind xmlns:D="DAV:"> <D:prop xmlns:R="http://ns.example.com/boxschema/"> <R:bigbox/> <R:author/> <R:DingALing/> <R:Random/> </D:prop> </D:propfind> '; # Example in section 9.1.5 of RFC4918 my $txt2 = '<?xml version="1.0" encoding="utf-8" ?> <propfind xmlns="DAV:"> <propname/> </propfind> ';

The first example uses 'D' as a prefix for 'DAV' (xmlns:D="DAV:") and the second uses "DAV" as the default name space.

The RFC says of the second example... "[$txt2] demonstrates the use of XML namespace scoping and the default namespace. Since the "xmlns" attribute does not contain a prefix, the namespace applies by default to all enclosed elements.".

The code I am using is:

#!/usr/bin/perl -w use strict; use XML::LibXML; sub doitLX { my $contentRef = shift or die; my $content = $$contentRef; my $xpath = shift or die; $|++; my $parser = XML::LibXML->new(); my $dom = $parser->parse_string($content); my $doc = $dom->documentElement(); my @propfind = (); eval { @propfind = $dom->findnodes($xpath); }; if($@){ print "Failed ".ref($dom)."::findnodes('$xpath') \$@ $@\n"; }else{ print ref($dom)."::findnodes('$xpath') ".scalar(@propfind)." nodes +\n\n"; } eval { @propfind = $doc->findnodes($xpath); }; if($@){ print "Failed ".ref($doc)."::findnodes('$xpath') \$@ $@\n"; }else{ print ref($doc)."::findnodes('$xpath') ".scalar(@propfind)." nodes +\n\n"; } } # Example in section 9.1.3 of RFC4918 my $txt1 = '<?xml version="1.0" encoding="utf-8" ?> <D:propfind xmlns:D="DAV:"> <D:prop xmlns:R="http://ns.example.com/boxschema/"> <R:bigbox/> <R:author/> <R:DingALing/> <R:Random/> </D:prop> </D:propfind> '; # Example in section 9.1.5 of RFC4918 my $txt2 = '<?xml version="1.0" encoding="utf-8" ?> <propfind xmlns="DAV:"> <propname/> </propfind> '; my $xpath1 = '/DAV:propfind/DAV:prop'; my $xpath2 = '/DAV:propfind/DAV:propname'; my $xpath3 = '/D:propfind/D:prop'; my $xpath4 = '/D:propfind/D:propname'; my $xpath5 = '/propfind/prop'; my $xpath6 = '/propfind/propname'; print "\$txt1 \$xpath1 \n"; &doitLX(\$txt1, $xpath1); print "\$txt2 \$xpath2 \n"; &doitLX(\$txt2, $xpath2); print "\$txt1 \$xpath3 \n"; &doitLX(\$txt1, $xpath3); print "\$txt2 \$xpath4 \n"; &doitLX(\$txt2, $xpath4); print "\$txt1 \$xpath5 \n"; &doitLX(\$txt1, $xpath5); print "\$txt2 \$xpath6 \n"; &doitLX(\$txt2, $xpath6);

The output is:

$txt1 $xpath1 Failed XML::LibXML::Document::findnodes('/DAV:propfind/DAV:prop') $@ X +Path error : Undefined namespace prefix error : xmlXPathCompiledEval: evaluation failed Failed XML::LibXML::Element::findnodes('/DAV:propfind/DAV:prop') $@ XP +ath error : Undefined namespace prefix error : xmlXPathCompiledEval: evaluation failed $txt2 $xpath2 Failed XML::LibXML::Document::findnodes('/DAV:propfind/DAV:propname') +$@ XPath error : Undefined namespace prefix error : xmlXPathCompiledEval: evaluation failed Failed XML::LibXML::Element::findnodes('/DAV:propfind/DAV:propname') $ +@ XPath error : Undefined namespace prefix error : xmlXPathCompiledEval: evaluation failed $txt1 $xpath3 XML::LibXML::Document::findnodes('/D:propfind/D:prop') 1 nodes XML::LibXML::Element::findnodes('/D:propfind/D:prop') 1 nodes $txt2 $xpath4 Failed XML::LibXML::Document::findnodes('/D:propfind/D:propname') $@ X +Path error : Undefined namespace prefix error : xmlXPathCompiledEval: evaluation failed Failed XML::LibXML::Element::findnodes('/D:propfind/D:propname') $@ XP +ath error : Undefined namespace prefix error : xmlXPathCompiledEval: evaluation failed $txt1 $xpath5 XML::LibXML::Document::findnodes('/propfind/prop') 0 nodes XML::LibXML::Element::findnodes('/propfind/prop') 0 nodes $txt2 $xpath6 XML::LibXML::Document::findnodes('/propfind/propname') 0 nodes XML::LibXML::Element::findnodes('/propfind/propname') 0 nodes

As far as I can tell the XPats:

my $xpath1 = '/DAV:propfind/DAV:prop'; my $xpath2 = '/DAV:propfind/DAV:propname';

are the correct ones. But I cannot find any documentation that addresses default name spaces. I am lost...

Worik


In reply to xmlns and XML::LibXML by Anonymous Monk

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.