Reputation: 107
I have an xml file like this
<?xml version="1.0" encoding="UTF-8"?>
<xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve">
<f href="C:\cFGCACHE-058cef2b85c09427e606b143bd75248e252d004e\alternative.pdf"/>
<ids modified="BF43C70442ECB74FA49833BBA44D4679" original="B4870CC046121A41B7D8F0838C87256D"/>
<fields>
<field name="FormInstanceID">
<value>SRSQSC88E48-1-1.320</value>
</field>
<field name="txt_bestelltKW">
<value></value>
</field>
</fields>
</xfdf>
Now I need to extract the value of the f href attribute. I tried it with single line processing but there is certainly a better way to do it. Any idea?
Thanks
Upvotes: 3
Views: 1469
Reputation: 53478
I like XML::Twig
. Not to dispute previous poster's solution, I'd do it like this:
use strict;
use warnings;
use XML::Twig;
sub extract_f {
my ( $twig, $f ) = @_;
print $f->atts->{'href'}, "\n";
}
my $twig = XML::Twig->new( twig_handlers => { 'f' => \&extract_f }, );
$twig->parse( \*DATA );
__DATA__
<?xml version="1.0" encoding="UTF-8"?><xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve" >
<f href="C:\cFGCACHE-058cef2b85c09427e606b143bd75248e252d004e\alternative.pdf"/>
<ids modified="BF43C70442ECB74FA49833BBA44D4679" original="B4870CC046121A41B7D8F0838C87256D"/>
<fields>
<field name="FormInstanceID">
<value>SRSQSC88E48-1-1.320</value>
</field>
<field name="txt_bestelltKW">
<value></value>
</field>
</fields>
</xfdf>
The major reason I like XML::Twig is because it allows purging XML as you go - so if you have a lot of XML to work with, it can be invaluable.
Upvotes: 2
Reputation: 35198
I would recommend either XML::LibXML
or XML::Twig
.
I would consider your goal rather trivial if not for having to deal with namespaces. However, the following demonstrates how to use XML::LibXML
to pull your desired value while ignoring the namespaces:
use strict;
use warnings;
use XML::LibXML;
my $dom = XML::LibXML->load_xml( IO => \*DATA );
my ($f) = $dom->findnodes('//*[local-name()="f"]');
print $f->getAttribute('href'), "\n";
__DATA__
<?xml version="1.0" encoding="UTF-8"?>
<xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve">
<f href="C:\cFGCACHE-058cef2b85c09427e606b143bd75248e252d004e\alternative.pdf"/>
<ids modified="BF43C70442ECB74FA49833BBA44D4679" original="B4870CC046121A41B7D8F0838C87256D"/>
<fields>
<field name="FormInstanceID">
<value>SRSQSC88E48-1-1.320</value>
</field>
<field name="txt_bestelltKW">
<value></value>
</field>
</fields>
</xfdf>
Outputs:
C:\cFGCACHE-058cef2b85c09427e606b143bd75248e252d004e\alternative.pdf
Upvotes: 0
Reputation: 241738
After fixing the typo in your XML, I was able to extract the value with the following code:
#!/usr/bin/perl
use warnings;
use strict;
use XML::LibXML;
my $dom = 'XML::LibXML'->load_xml( file => 'example.xml' );
my $xc = 'XML::LibXML::XPathContext'->new;
$xc->registerNs('x', 'http://ns.adobe.com/xfdf/');
for my $href ($xc->findvalue('//x:f/@href', $dom)) {
print $href, "\n";
}
I usually find XML::LibXML too verbose, so I'd use XML::XSH2:
open example.xml ;
register-namespace x http://ns.adobe.com/xfdf/ ;
for //x:f echo @href ;
Upvotes: 4