Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Re: Creating Nodes in namespace with XML::LibXML

by Anonymous Monk
on Jun 04, 2015 at 23:49 UTC ( [id://1129142]=note: print w/replies, xml ) Need Help??


in reply to Creating Nodes in namespace with XML::LibXML

Please have a look at How do I post a question effectively? - you haven't given a runnable piece of code, the expected output, and the current output.

You seem to want to avoid passing the document object around like it's a bad thing - it's not, in fact, if I understand your question correctly, then the solution is based on that you will need to pass the XML::LibXML::Document object around and add your elements to the document as you create them, instead of handling unbound nodes.

use warnings; use strict; use XML::LibXML; my $doc = XML::LibXML::Document->new; my $el1 = $doc->createElementNS("namespace0","aaa"); $el1->setNamespace("namespace1","p1",0); $el1->setNamespace("namespace2","p2",0); $doc->setDocumentElement($el1); my $el2 = $doc->createElement("bbb"); $el2->setNamespace("namespace2","p2",1); $el1->appendChild($el2); my $el3 = $doc->createElementNS("namespace0","ccc"); $el1->appendChild($el3); my $el4 = $doc->createElement("p1:ddd"); $el3->appendChild($el4); print $doc->toString(1); __END__ <?xml version="1.0"?> <aaa xmlns="namespace0" xmlns:p1="namespace1" xmlns:p2="namespace2"> <p2:bbb/> <ccc> <p1:ddd/> </ccc> </aaa>

Note how the namespace declarations are automatically reused. This is actually documented in XML::LibXML::Element's setNamespace. Since you seem to want to work with XML::LibXML more closely, I strongly suggest you take the time to read all of its documentation (starting with XML::LibXML::Node, XML::LibXML::Element and XML::LibXML::Document).

Replies are listed 'Best First'.
Re^2: Creating Nodes in namespace with XML::LibXML
by worik (Sexton) on Jun 05, 2015 at 01:42 UTC

    you haven't given a runnable piece of code
    True. My bad. Sorry

    That said I have worked out the XML::LibXML approach.

    For example I want to build:

    <?xml version="1.0" encoding="UTF-8"?> <O:ABC xmlns:O="ONE:" xmlns:T="two:IS:a_namEsp"> <O:ZZZ/> <T:ZZZ> <O:QWERTY> <T:UIOP/> </O:QWERTY> </T:ZZZ> </O:ABC>

    The following code does it....

    #!/usr/bin/perl -w use strict; use XML::LibXML; # NAmespaces my $ONE_ns = 'ONE:'; my $ONE_pfx = 'O'; my $TWO_ns = 'two:IS:a_namEsp'; my $TWO_pfx = 'T'; # The XML Document my $DOC = XML::LibXML->createDocument( "1.0", "UTF-8" ); # Set the root my $root = $DOC->createElement('ABC'); $DOC->setDocumentElement($root); # Establish namespaces $root->setNamespace($ONE_ns, $ONE_pfx, 1); $root->setNamespace($TWO_ns, $TWO_pfx, 0); # Build the document tree my $this = &appendOZ($root); $this = &appendTZ($this); print $DOC->toString(1); sub appendOZ { my $root = shift or die; $root->addNewChild($ONE_ns, 'ZZZ'); return $root; } sub appendTZ { my $root = shift or die; my $this = $root->addNewChild($TWO_ns, 'ZZZ'); &appendOQ($this); return $root; } sub appendOQ { my $root = shift or die; my $this = $root->addNewChild($ONE_ns, 'QWERTY'); &appendTU($this); return $root; } sub appendTU { my $root = shift or die; $root->addNewChild($TWO_ns, 'UIOP'); return $root; }

    Where a sub tree is a leaf it says:

    my $root = shift or die; $root->addNewChild(<namespace>, <name>); return $root;

    Where the sub-tree is the root of another sub-tree itself it says:

    sub appendOQ { my $root = shift or die; # Make this node my $this = $root->addNewChild(<namesace>, <name>); # Append sub tree &appendTU($this); return $root; }

    This works out nicely and does what I want. If I want a different tree:

    <?xml version="1.0" encoding="UTF-8"?> <O:ABC xmlns:O="ONE:" xmlns:T="two:IS:a_namEsp"> <O:ZZZ/> <T:ZZZ> <O:QWERTY> <T:UIOP/> </O:QWERTY> </T:ZZZ> <O:QWERTY> <T:UIOP/> </O:QWERTY> </O:ABC>

    I change the core of the programme to:

    # Build the document tree my $this = &appendOZ($root); $this = &appendTZ($this); $this = &appendOQ($this); print $DOC->toString(1);

    What I expected to be writing, when adding a sub-tree, was some thing like:

    # Make this node my $this = $root->addNewChild(<namesace>, <name>); # Append sub tree $this->append(&buildSubTree) return $this;

    The only reason (I can see, with my inexperience) to pass the root is for the namespace prefix information. It is nice to use prefixes, and I can see with hindsight that it would require some post processing of the tree to achieve that. So what I was expecting is not the "XML::LibXML" way. Fair enough

    So the answer to my question was "No, yes". Simple really

    Another thing. Some one said:

    I strongly suggest you take the time to read all of its documentation
    . Sensible advice. I have been doing exactly that. There are thousands and thousands of lines there, and they are organised as a reference not an introduction. It is hard to start the learning curve with XML::LibXML. In the absence of an introductory document there will be stupid sounding questions from beginners.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1129142]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (3)
As of 2024-03-29 14:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found