Skip Menu |

This queue is for tickets about the XML-SimpleObject-LibXML CPAN distribution.

Report information
The Basics
Id: 33011
Status: open
Priority: 0/
Queue: XML-SimpleObject-LibXML

People
Owner: Nobody in particular
Requestors: hboehm [...] brutus.nic.dtag.de
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.60
Fixed in: (no value)



Subject: bugs in subroutines 'child' and 'children' when calling with arguments
according to the documentation, calling subroutine 'children' with argument "NAME" should return an array of all elements directly below the top-level that have the element name "NAME". Calling 'child' with argument "NAME" should return a single child element with name "NAME". It turned out that both methods don't just look up the elements "directly below the top-level" but perform a depth search on the sub-tree instead. Look at the following example: <datamodel> <level1> <level2> <data>333</data> </level2> </level1> <data>111</data> </datamodel> When <datamodel> is the top-level, calling 'children('data')' returns both <data> elements (the one having value 333 and the one having value 111). Calling 'child('data')' returns the <data> element having value 333. The following patch ensures that only the elements directly below the top-level (the children) are considered when the subroutines are executed. patch: --- LibXML.pm.original Wed Nov 10 18:48:26 2004 +++ LibXML.pm Thu Feb 7 17:48:08 2008 @@ -168,7 +168,7 @@ } else { - my ($element) = $self->{_DOM}->getElementsByTagName($tag); + my ($element) = $self->{_DOM}->getChildrenByTagName($tag); return unless ($element); my $node = new XML::SimpleObject::LibXML ($element); return $node; @@ -220,7 +220,7 @@ } else { my @nodelist; - foreach my $node ($self->{_DOM}->getElementsByTagName($tag)) { + foreach my $node ($self->{_DOM}->getChildrenByTagName($tag)) { next if ($node->nodeType == TEXT_NODE); push @nodelist, new XML::SimpleObject::LibXML ($node); } I attached 3 files: bug_test.xml => the XML example from above bug_test.pl => perl script testing the result of both subroutines patch => the proposed patch my perl version is: v5.6.2 built for sun4-solaris-64int my OS is: SunOS 5.9 Generic_118558-34 sun4u sparc SUNW,A70
Subject: bug_test.pl
#!/usr/bin/perl use strict; use XML::SimpleObject::LibXML; my $parser = new XML::LibXML; my $xmlobj = new XML::SimpleObject::LibXML ($parser->parse_file("./bug_test.xml")); my $datamodel = $xmlobj->child('datamodel'); print "return value of \$datamodel->children(\'data\'):\n"; foreach my $element ($datamodel->children("data")) { print "data: ".$element->value."\n"; } print "\nreturn value of \$datamodel->child(\"data\"):\n"; if (defined $datamodel->child("data")) { print "data: " . $datamodel->child("data")->value . "\n"; } else { print "no data!\n"; }
Subject: bug_test.xml
<datamodel> <level1> <level2> <data>333</data> </level2> </level1> <data>111</data> </datamodel>
Subject: patch
Download patch
application/octet-stream 806b

Message body not shown because it is not plain text.

From: sabol [...] alderaan.gsfc.nasa.gov
On Fri Feb 08 07:15:17 2008, habo wrote: Show quoted text
> according to the documentation, calling subroutine 'children' with > argument "NAME" should return an array of all elements directly below > the top-level that have the element name "NAME". Calling 'child' with > argument "NAME" should return a single child element with name "NAME". > > It turned out that both methods don't just look up the elements > "directly below the top-level" but perform a depth search on the > sub-tree instead.
First off, I love this module. My thanks to the author for releasing it and maintaining it over the years. Continued maintenance would be much appreciated. I recently came across this bug as well. Should the getElementsByTagNameNS method calls be changed to getChildrenByTagNameNS method calls in the child() and children() methods as well? I presume so and have attached a updated patch.
Subject: XML-SimpleObject-LibXML.patch
--- LibXML.pm~ 2004-11-10 12:48:26.000000000 -0500 +++ LibXML.pm 2010-04-28 20:12:31.184068000 -0400 @@ -4,7 +4,7 @@ use XML::LibXML 1.53; use XML::LibXML::Common; -our $VERSION = '0.60'; +our $VERSION = '0.60.1'; sub attributes { my $self = shift; @@ -161,14 +161,14 @@ } elsif ($self->hasNamespaces()) { my ($namespaceURI, $localName) = $self->_parseTagName($tag, ELEMENT_NODE); - my ($element) = $self->{_DOM}->getElementsByTagNameNS($namespaceURI, $localName); + my ($element) = $self->{_DOM}->getChildrenByTagNameNS($namespaceURI, $localName); return unless ($element); my $node = new XML::SimpleObject::LibXML ($element); return $node; } else { - my ($element) = $self->{_DOM}->getElementsByTagName($tag); + my ($element) = $self->{_DOM}->getChildrenByTagName($tag); return unless ($element); my $node = new XML::SimpleObject::LibXML ($element); return $node; @@ -212,7 +212,7 @@ if ($self->hasNamespaces()) { my ($namespaceURI, $localName) = $self->_parseTagName($tag, ELEMENT_NODE); my @nodelist; - foreach my $node ($self->{_DOM}->getElementsByTagNameNS($namespaceURI, $localName)) { + foreach my $node ($self->{_DOM}->getChildrenByTagNameNS($namespaceURI, $localName)) { next if ($node->nodeType == TEXT_NODE); push @nodelist, new XML::SimpleObject::LibXML ($node); } @@ -220,7 +220,7 @@ } else { my @nodelist; - foreach my $node ($self->{_DOM}->getElementsByTagName($tag)) { + foreach my $node ($self->{_DOM}->getChildrenByTagName($tag)) { next if ($node->nodeType == TEXT_NODE); push @nodelist, new XML::SimpleObject::LibXML ($node); }