How to extract attribute value from XML file
I have 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 attribute of the href. I tried it with one line, but by far the best way to do it. Any idea?
thank
source to share
After correcting 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 would use XML :: XSH2 :
open example.xml ;
register-namespace x http://ns.adobe.com/xfdf/ ;
for //x:f echo @href ;
source to share
I like it XML::Twig
. So as not to dispute the previous posters solution, I would 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 main reason I like XML :: Twig is that it allows you to flush the XML as you go - so if you have a lot of XML to work with, this can be invaluable.
source to share
I would recommend XML::LibXML
or XML::Twig
.
I would find your goal rather trivial without dealing with namespaces. However, below shows how to use XML::LibXML
to pull out the desired value while ignoring 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
source to share