Click here to get back home

Help with XML::Twig xpath syntax, please

 HomeNewsGroups | Search | About
 comp.lang.perl.modules    Post an article   get this group's latest topics as an RSS feed add this group's latest topics to your My MSN content add this group's latest topics to your My Yahoo content
Subject Author Date
Help with XML::Twig xpath syntax, please Henry Law 10-16-2005
Get Chitika Premium
Posted by Henry Law on October 16, 2005, 6:56 pm
Please log in for more thread options


I have a simple XML file which contains details of files in a directory
(the format is in the sample program below). I want to use XML::Twig
(which is in widespread use elsewhere in the program suite) to pull out
document elements corresponding to certain criteria, but I cannot for
the life of me work out the syntax for the get_xpath method, despite
browsing Michel Rodriguez's XMLTwig site and his xpath tester page.

Here's a sample program; what it's intended to do is to pull out the
"bkfile" element which has dbid=392; it does that, but pulls out much
else besides - including the other bkfile element whose dbid doesn't
match - and I can't find out what I'm doing wrong. All help very
gratefully received. XML::Twig is a great module and I've used it
extensively elsewhere; it would be a nuisance to have to use some other
XML module for this task.

This is XML::Twig 3.20 running under ActiveState Perl v5.8.7 and Windows
XP (fully patched).

-------------- sample program -------------
use strict;
use warnings;

use XML::Twig;

my $xmldoc = new XML::Twig;
my $xmlsource =<<"ENDXML";
<bkdirectory>
<bkfile>
<dbid>393</dbid>
<b_size>177</b_size>
</bkfile>
<bkfile>
<dbid>392</dbid>
<b_size>460</b_size>
</bkfile>
</bkdirectory>
ENDXML

$xmldoc->parse($xmlsource);

my @bkfiles = $xmldoc->get_xpath('//bkfile[string(dbid)="392"]]');

print "\@bkfiles has ",scalar @bkfiles," elements\n\n";
foreach my $elt (@bkfiles) {
        print "----",$elt->name,"\n";
        $elt->print;
        print "\n";
}
-- output from sample: one line may fold, sorry -------
F:\>tryit.pl
@bkfiles has 11 elements

----bkdirectory
<bkdirectory><bkfile><dbid>393</dbid><b_size>177</b_size></bkfile><bkfile><dbid>392</dbid><b_size>460</b_size></bkfile></bkdirectory>
----bkfile
<bkfile><dbid>393</dbid><b_size>177</b_size></bkfile>
----dbid
<dbid>393</dbid>
----#PCDATA
393
----b_size
<b_size>177</b_size>
----#PCDATA
177
----bkfile
<bkfile><dbid>392</dbid><b_size>460</b_size></bkfile>
----dbid
<dbid>392</dbid>
----#PCDATA
392
----b_size
<b_size>460</b_size>
----#PCDATA
460

--

Henry Law <>< Manchester, England


Posted by Michel Rodriguez on October 17, 2005, 3:15 pm
Please log in for more thread options


Henry Law wrote:
> I have a simple XML file which contains details of files in a directory
> (the format is in the sample program below). I want to use XML::Twig
> (which is in widespread use elsewhere in the program suite) to pull out
> document elements corresponding to certain criteria, but I cannot for
> the life of me work out the syntax for the get_xpath method, despite
> browsing Michel Rodriguez's XMLTwig site and his xpath tester page.
>
> Here's a sample program; what it's intended to do is to pull out the
> "bkfile" element which has dbid=392; it does that, but pulls out much
> else besides - including the other bkfile element whose dbid doesn't
> match - and I can't find out what I'm doing wrong. All help very
> gratefully received. XML::Twig is a great module and I've used it
> extensively elsewhere; it would be a nuisance to have to use some other
> XML module for this task.
>
> my @bkfiles = $xmldoc->get_xpath('//bkfile[string(dbid)="392"]]');

Oops! You found the edge of XML::Twig's rudimentary XPath support. It
should really throw an error and admint that it can't deal with this
type of query. I will fix this (by throwing said error),

If you have XML::XPath installed, or if you can install it on that
machine, then you can use XML::TwigXPath instead of XML::Twig, and then
you get full XPath support through the findnodes method.

Let me know if this helps.

--
mirod


Posted by Henry Law on October 17, 2005, 7:32 pm
Please log in for more thread options


Michel Rodriguez wrote:

> Oops! You found the edge of XML::Twig's rudimentary XPath support. It
> should really throw an error and admint that it can't deal with this
> type of query. I will fix this (by throwing said error),
>
> If you have XML::XPath installed, or if you can install it on that
> machine, then you can use XML::TwigXPath instead of XML::Twig, and then
> you get full XPath support through the findnodes method.
>
> Let me know if this helps.

Done that and it does exactly what I want. Wasn't hard to install the
additional module either. Thank you.

--

Henry Law <>< Manchester, England


Posted by Jordi Bernabeu (w00dy) on October 17, 2005, 7:57 pm
Please log in for more thread options


Henry Law wrote:
> [...]
> Here's a sample program; what it's intended to do is to pull out the
> "bkfile" element which has dbid=392; it does that, but pulls out much
> else besides - including the other bkfile element whose dbid doesn't
> match - and I can't find out what I'm doing wrong. All help very
> gratefully received. XML::Twig is a great module and I've used it
> extensively elsewhere; it would be a nuisance to have to use some other
> XML module for this task.
>
> This is XML::Twig 3.20 running under ActiveState Perl v5.8.7 and Windows
> XP (fully patched).
>
> -------------- sample program -------------
> use strict;
> use warnings;
>
> use XML::Twig;
>
> my $xmldoc = new XML::Twig;
> my $xmlsource =<<"ENDXML";
> <bkdirectory>
> <bkfile>
> <dbid>393</dbid>
> <b_size>177</b_size>
> </bkfile>
> <bkfile>
> <dbid>392</dbid>
> <b_size>460</b_size>
> </bkfile>
> </bkdirectory>
> ENDXML
>
> $xmldoc->parse($xmlsource);
>
> my @bkfiles = $xmldoc->get_xpath('//bkfile[string(dbid)="392"]]');
>
> print "\@bkfiles has ",scalar @bkfiles," elements\n\n";
> foreach my $elt (@bkfiles) {
> print "----",$elt->name,"\n";
> $elt->print;
> print "\n";
> }

Hi,

Have you tried using TwigHandlers when creating $xmldoc?

With get_xpath() you get the whole parent-tree (up to the root, hence
you get the whole document).

Try putting your xpath in TwigHandlers and your processing in a sub,
like this:

--------------------------- sample program -------------------
#!/usr/bin/perl
use strict;
use warnings;

use XML::Twig;

my $xmlsource =<<"ENDXML";
<bkdirectory>
<bkfile>
<dbid>393</dbid>
<b_size>177</b_size>
</bkfile>
<bkfile>
<dbid>392</dbid>
<b_size>460</b_size>
</bkfile>
</bkdirectory>
ENDXML

my $xmldoc = new XML::Twig( TwigHandlers =>
{
'bkfile[string(dbid)="392"] => \&process
}
);
$xmldoc->parse($xmlsource);

sub process
{
my ($twig, $element) = @_;
print $element->name,"\n";
foreach my $child ($element->children)
{
print $child->name,": ",$child->text,"\n";
}
}
--------------------- /sample program ----------------------------

Hope this helps.

Jordi (w00dy)


Similar ThreadsPosted
XML::Twig::XPath - strange problem November 10, 2005, 9:44 am
XPath to Line Number? June 26, 2007, 2:39 pm
XML::XPath delete function November 26, 2007, 3:35 pm
Parsing Doctype Entitites using XML::XPath November 5, 2004, 10:13 am
Net::SFTP ssh_args=>[ ] syntax question... August 19, 2004, 9:48 am
Class::MethodMaker v2 syntax help requested February 7, 2005, 9:33 pm
Pod syntax and hyperlinks to =item entries December 8, 2005, 8:37 pm
Email address syntax check? December 2, 2006, 2:58 pm
Syntax error using cpan leads to bizarre behavior September 10, 2004, 6:32 pm
XML Twig help April 8, 2005, 2:18 pm

Our other projects:

Art Dolls, Fairies and Mermaids - Sunnyfaces.net

Roy's Linux, Programming and Search Engines messages

1-Script XML SitemapXML Sitemap