|
Posted by mcvallet on March 9, 2006, 1:27 pm
Please log in for more thread options
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)
<quiz nbQuestions="30" >
<questionBlock type="textField" id="1" mandatory = "true">
<title>title</title>
<image>image link</image>
<question>First question</question>
<answers isTrue="true"> correct answer 1 </answers>
<followUpQuestion>
<questionBlock type="textField" id="2">
<question>question 2</question>
<answers isTrue="true"> correct answer 2</answers>
</questionBlock>
<questionBlock type="trueFalse" id="3">
<question>question 3</question>
<answers id="" isTrue="false">answer 1 </answers>
<answers isTrue="true">answer 2</answers>
</questionBlock>
....
</followUpQuestion>
</questionBlock>
<questionBlock type="textField" id="7">
<title>Title</title>
<question> question 7 </question>
<answers isTrue="true"> correct answer </answers>
</questionBlock>
...
</quiz>
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
|
|
Posted by mirod on March 10, 2006, 3:57 am
Please log in for more thread options
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__
<quiz nbQuestions="30" >
<questionBlock type="textField" id="1" mandatory = "true">
<title>title</title>
<image>image link</image>
<question>First question</question>
<answers isTrue="true"> correct answer 1 </answers>
<followUpQuestion>
<questionBlock type="textField" id="2">
<question>question 2</question>
<answers isTrue="true"> correct answer 2</answers>
</questionBlock>
<questionBlock type="trueFalse" id="3">
<question>question 3</question>
<answers id="" isTrue="false">answer 1 </answers>
<answers isTrue="true">answer 2</answers>
</questionBlock>
</followUpQuestion>
</questionBlock>
<questionBlock type="textField" id="7">
<title>Title</title>
<question> question 7 </question>
<answers isTrue="true"> correct answer </answers>
</questionBlock>
</quiz>
--
Michel Rodriguez
Perl & XML
xmltwig.com
|
|
Posted by mcvallet on March 10, 2006, 5:04 pm
Please log in for more thread options
thanks, it works now
|
|
Posted by mcvallet on March 10, 2006, 7:53 pm
Please log in for more thread options
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;
}
|
| Similar Threads | Posted | | XML Parsing too slow | November 19, 2005, 7:29 am |
| HTML parsing | March 21, 2005, 3:24 pm |
| CGI.pm parsing odity | May 16, 2006, 10:01 am |
| Image data parsing | October 27, 2004, 3:36 pm |
| Parsing OpenOffice Spreadsheets | April 25, 2005, 7:23 pm |
| can't find xml-parsing module... | May 27, 2006, 5:30 am |
| Lemur parsing module | June 20, 2006, 10:44 pm |
| XML::Atom::Feed - parsing at all? | January 20, 2008, 5:04 pm |
| Parsing AVI header information | June 8, 2008, 11:08 pm |
| Parsing Doctype Entitites using XML::XPath | November 5, 2004, 10:13 am |
|