roman has asked for the wisdom of the Perl Monks concerning the following question:

Dear monks,

does anyone know how to simply solve following annoyance (not a real problem)?

Building DOM by XML::LibXML I create new elements via createElementNS method of XML document. When such document is serialized, every element contains the namespace declaration. Due to this declarations, the document is not very readable and occupies too much space on my screen.

Is there a way how to get rid of these declarations in resulting document and left only those "necessary" (in document element).

use strict; use warnings; use XML::LibXML; my $ns = 'http://www.example.com'; my $doc = XML::LibXML::Document->new; $doc->setDocumentElement($doc->createElementNS($ns, 'q:one')); $doc->documentElement->appendChild($doc->createElementNS($ns, 'q:two') +); $doc->documentElement->appendChild($doc->createElementNS($ns, 'q:three +')); warn $doc->toString(1);
The result is
<?xml version="1.0"?> <q:one xmlns:q="http://www.example.com"> <q:two xmlns:q="http://www.example.com"/> <q:three xmlns:q="http://www.example.com"/> </q:one>

Thanks for any advice

Roman

Replies are listed 'Best First'.
Re: XML::LibXML and too many namespace declarations
by guliver (Friar) on Mar 27, 2007 at 10:43 UTC
    Just use createElement instead of createElementNS for subsequent nodes of the same namespace.
    use strict; use warnings; use XML::LibXML; my $ns = 'http://www.example.com'; my $doc = XML::LibXML::Document->new; $doc->setDocumentElement($doc->createElementNS($ns, 'q:one')); $doc->documentElement->appendChild($doc->createElement($ns, 'q:two')); $doc->documentElement->appendChild($doc->createElement($ns, 'q:three') +); warn $doc->toString(1);

      It works, but from the DOM perspective, the nodes created by createElement don't seem to have any namespace attached

      use strict; use XML::LibXML; my $ns = 'http://www.example.com'; my $doc = XML::LibXML::Document->new; $doc->setDocumentElement($doc->createElementNS($ns, 'q:one')); my $elem_two = $doc->documentElement->appendChild($doc->createElement +NS($ns, 'q:two')); my $elem_three = $doc->documentElement->appendChild($doc->createElemen +t('q:three')); warn $doc->toString(1); # look at the namespace in DOM warn 'namespace of q:two is ', $elem_two->namespaceURI, "\n"; warn 'namespace of q:three is ', $elem_three->namespaceURI, "\n"; # via findnodes warn 'q:* nodes are ', join (',', map {$_->nodeName} $doc->documentEle +ment->findnodes('//q:*')), "\n";

      The result is:

      <?xml version="1.0"?> <q:one xmlns:q="http://www.example.com"> <q:two xmlns:q="http://www.example.com"/> <q:three/> </q:one> namespace of q:two is http://www.example.com namespace of q:three is q:* nodes are q:one,q:two

      Moreover the manual of XML::LibXML::DOM states:

      It is also important to repeat the specification: While working with namespaces you should use the namespace aware functions instead of the simplified versions.