XML::DOM parsing pb

XML::DOM parsing pb

am 09.03.2006 19:27:36 von mcvallet

Hi,
I have a simple parsing problem (I know it is simple but I just started
with XML::DOM) that I do not know how to resolve :
here is the xml file : (well at lease part of it)


title
image link
First question
correct answer 1


question 2
correct answer 2


question 3
answer 1
answer 2

....



Title
question 7
correct answer

...

and this is what I want to do with it :
- for each questionBlock that does not belong to
a followUpQuestion{
do something
}
I do not know how to formulate this condition.
If I simply do this :
foreach my $question ( $doc->getElementsByTagName('questionBlock')) {}
I just end up with all the questionBlocks even the ones present in the
followUp part... and this is not what I want. Does anyone have any idea
?
thank you,
mc

Re: XML::DOM parsing pb

am 10.03.2006 09:57:34 von mirod

mcvallet@hotmail.com wrote:

> - for each questionBlock that does not belong to a followUpQuestion{
> do something
> }
> I do not know how to formulate this condition.

You have several options:

- write an ancestors function/method, using getParentNode, test nodes
returned by $doc->getElementsByTagName('questionBlock'), if they have a

followUpQuestion{ ancestor, ignore them

- use XML::DOM::XPath (you need to install it, it reuqires XML::XPath)
and use XPath to fond exactly what you want

- ditch XML::DOM altogether and use XML::LibXML (the code will be very
similar to what you write with XML::DOM::XPath), you will get better
performance and a more powerful DOM (+XPath, XInclude, HTML parsing...)
implementation

Here is the code using XML::DOM::XPath

#!/usr/bin/perl

use strict;
use warnings;

use XML::DOM::XPath;

my $parser= XML::DOM::Parser->new();
my $doc = $parser->parse ( \*DATA);

# probably works for you
#my $q='/quiz/questionBlock';

# exactly what you said
my $q= '//questionBlock[not (./ancestor::followUpQuestion)]';

foreach my $question ( $doc->findnodes( $q))
{ print $question->getAttribute( 'id'), ": ", $question->findvalue(
'./title'), "\n" }

__DATA__


title
image link
First question
correct answer 1


question 2
correct answer 2


question 3
answer 1
answer 2




Title
question 7
correct answer




--
Michel Rodriguez
Perl & XML
xmltwig.com

Re: XML::DOM parsing pb

am 10.03.2006 23:04:30 von mcvallet

thanks, it works now

Re: XML::DOM parsing pb

am 11.03.2006 01:53:24 von mcvallet

this is the solution I found
########################################################
# getChildrenNamed(Node node, String tagName) #
# return the children of a given tag for a given node #
########################################################

sub getChildrenNamed($$) {
my $doc = $_[0];
my $nodeName = $_[1];
my $num = $doc->getChildIndex( $doc->getLastChild );
my @childrenNamed;
for ( my $i = 0 ; $i < $num ; $i++ ) {
my $childNamed = $doc->getChildAtIndex($i);
if ( $childNamed->getNodeName =~ /$nodeName/ ) {
push @childrenNamed, $childNamed;
}
}
return @childrenNamed;
}