Re: XML::LibXML - Mixing XPath with a document fragment

Petr Pajas <[email protected]>
Newsgroups gmane.comp.lang.perl.xml
Message-ID <[email protected]>
On čt 29. ledna 2009, Petr Pajas wrote:
> On čt 29. ledna 2009, Emmanuel Rodriguez wrote:
> > Hi,
> >
> > I have an XML document that was generated with document
> > fragments by an external function. This gave me some struggle
> > because I was trying to use an XPath expression to access some
> > nodes and couldn't reach them. This is due to the fact that
> > even though the document fragment seems transparent it's still
> > in the document and brakes the parent/child/sibling relation
> > ship. This makes it a difficult to use XPath to search for
> > nodes.
> >
> > Is there a way to clean document of all document fragments
> > besides $xml =
> > XML::LibXML->new()->parse_string($xml->toString()); ? Should
> > document fragments be avoided?
> >
> > For the curious, I have attached a test case that shows the
> > problems I had parsing the document.
>
> Hallo Emmanuel!
>
> A fragment node should never have appeared as a child of another
> node; that's the bug!

oh, and the bug is documented:-)

addChild:

As an alternative to appendChild() one can use the addChild() 
function. This function is a bit faster, because it avoids all DOM
conformity checks.

Well, in that case I might just add a simple node-type test and 
croak on fragments (and possibly other invalid node types). That 
will not cause any significant slow down.

One should use appendChild() for correct DOM behavior. 

Best,

-- Petr


> XML::LibXML should follow DOM spec [1], which says that attaching
> a document fragment to a node should result in moving the
> document fragment's children to the child list of the node, not
> in attaching the document fragment itself to the node. This seems
> to be a gap in XML::LibXML code, where addChild simply calls
> xmlAddChild without checking the node type; since xmlAddChild
> does not seem to do the job, I should add some code to handle
> fragments in a special way. addSibling seems to suffer from the
> same problem.
>
> So the following part from your test case:
>
> 	# Add the child elements through a document fragment
> 	my $fragment = $xml->createDocumentFragment();
> 	$root->addChild($fragment);
> 	foreach my $id (1 .. 3) {
> 		my $node = XML::LibXML::Element->new('child');
> 		$node->setAttribute(id => $id);
> 		$fragment->addChild($node);
> 	}
>
> should behave like a no-op, unless you rewrite it as
>
> 	# Add the child elements through a document fragment
> 	my $fragment = $xml->createDocumentFragment();
> 	foreach my $id (1 .. 3) {
> 		my $node = XML::LibXML::Element->new('child');
> 		$node->setAttribute(id => $id);
> 		$fragment->addChild($node);
> 	}
> 	$root->addChild($fragment);
>
> in which case all nodes created inside the foreach loop and
> attached to the fragment should be re-attached to $root on
> $root->addChild($fragment), leaving the fragment empty.
>
> I suggest you avoid calling addChild with a fragment as argument
> until XML::LibXML is fixed, which I'm gonna do now:-)
>
> Thanks for pointing this out. Best,
>
> [1] http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-B63ED1A3
>
> -- Petr
> _______________________________________________
> Perl-XML mailing list
> [email protected]
> To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs


_______________________________________________
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.