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 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;
}