snehit.ar has asked for the wisdom of the Perl Monks concerning the following question:

<?xml version="1.0"?> <playlist> <movie id="tt0112384"> <title>Apollo 13</title> <director>Ron Howard</director> <release-date>1995-06-30</release-date> </movie> <movie id="tt0307479"> <title>Solaris</title> <director>Steven Soderbergh</director> <release-date>2002-11-27</release-date> </movie> <movie id="tt1731141"> <title>Ender's Game</title> <director>Gavin Hood</director> <release-date>2013-11-01</release-date> </movie> </playlist>
I want to retrieve value of <release-date> element where <title> having value 'Solaris' and not other title elements.
use warnings; use strict; use XML::XPath; use Data::Dumper; my $xml = '../events.xml'; my $xp = XML::XPath->new(filename => $xml); my $nodeset = $xp->findnodes('//playlist'); my $records = []; foreach my $node ($nodeset->get_nodelist) { my $title = $xp->find('./title', $node); push @$records, { title => $title->string_value, }; } print Dumper($records);
I tired XPath something like  my $title= $xp->find("/playlist/movie[title='Solaris']/release-date", $node); But result is not as expected OutPut ::2002-11-27 Please do help !

Replies are listed 'Best First'.
Re: get specific value of element using xpath in perl
by haukex (Archbishop) on Jun 23, 2017 at 13:22 UTC
    I want to retrieve value of <release-date> element where <title> having value 'Solaris' and not other title elements. ... I tired XPath something like my $title= $xp->find("/playlist/movie[title='Solaris']/release-date", $node); But result is not as expected OutPut ::2002-11-27

    If the question is what is the <release-date> of the movie with the <title> "Solaris", isn't the correct answer "2002-11-27"? Both XML::LibXML and XML::XPath seem to work fine for me with the exact XPath expression you've shown. <update> All that the code you showed seems to try to do is build an array of hashes containing the <title> elements' values, which doesn't seem to fit your problem statement. </update>

    my $file = '/tmp/1193350.xml'; my $xpath = q{/playlist/movie[title='Solaris']/release-date}; use XML::LibXML; my $doc = XML::LibXML->load_xml(location=>$file); for my $node ( $doc->findnodes($xpath) ) { print "XML::LibXML: ",$node->textContent,"\n"; } use XML::XPath; my $xp = XML::XPath->new(filename=>$file); my $nodeset = $xp->find($xpath); for my $node ($nodeset->get_nodelist) { print " XML::XPath: ",$node->string_value,"\n"; } __END__ XML::LibXML: 2002-11-27 XML::XPath: 2002-11-27
      @haukex : Thanks a lot for the solution !
      I have tired with your code but not getting expected result . My samlple.xml
      <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <event_list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmln +s:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.hp.com/2009 +/software/opr/data_model" total_size="34" page_size="20" start_index= +"1" self="https://testurl/event_list?query=title+LIKE+%22PROBING%2810 +0%29%2425%22" type="urn:x-hp:2009:software:data_model:opr:type:event_ +list" version="1.1"> <drilldown_url> https://testurl/opr-web/opr-evt-browser</drilldown_url> <event relationships_included="true" self="https://testurl/event_l +ist/031c3c70-4ace-71e7-0b5b-88fb83170000" type="urn:x-hp:2009:softwar +e:data_model:opr:type:event" version="1.3"> <state> open</state> <severity> critical</severity> <priority> medium</priority> <category> SAR_OP_Service</category> <application> business_transaction_group</application> <time_created> 2017-06-06T15:37:13Z</time_created> <time_changed> 2017-06-20T10:37:20.098Z</time_changed> <time_received> 2017-06-20T10:37:20.156Z</time_received> <time_first_received> 2017-06-06T15:37:17.414Z</time_first_received> <custom_attribute_list self="https://testurl/event_list/031c3c +70-4ace-71e7-0b5b-88fb83170000/custom_attribute_list" type="urn:x-hp: +2009:software:data_model:opr:type:event:custom_attribute_list" versio +n="1.0"> <custom_attribute self="https://testurl/event_list/031c3c7 +0-4ace-71e7-0b5b-88fb83170000/custom_attribute_list/SAR_RemedyInciden +t" type="urn:x-hp:2009:software:data_model:opr:type:event:custom_attr +ibute" version="1.0"> <name> SAR_RemedyIncident</name> <value> INC000018745375</value> </custom_attribute> <custom_attribute self="https://testurl/event_list/031c3c7 +0-4ace-71e7-0b5b-88fb83170000/custom_attribute_list/SAR_RemedyQueue" +type="urn:x-hp:2009:software:data_model:opr:type:event:custom_attribu +te" version="1.0"> <name> SAR_RemedyQueue</name> <value> Coll@borate-L3</value> </custom_attribute> <custom_attribute self="https://testurl/event_list/031c3c7 +0-4ace-71e7-0b5b-88fb83170000/custom_attribute_list/SAR_RemedyStatus" + type="urn:x-hp:2009:software:data_model:opr:type:event:custom_attrib +ute" version="1.0"> <name> SAR_RemedyStatus</name> <value> Assigned</value> </custom_attribute> <custom_attribute self="https://testurl/event_list/031c3c7 +0-4ace-71e7-0b5b-88fb83170000/custom_attribute_list/SAR_SSRID" type=" +urn:x-hp:2009:software:data_model:opr:type:event:custom_attribute" ve +rsion="1.0"> <name> SAR_SSRID</name> <value> 957</value> </custom_attribute> <custom_attribute self="https://testurl/event_list/031c3c7 +0-4ace-71e7-0b5b-88fb83170000/custom_attribute_list/Service%20Name" t +ype="urn:x-hp:2009:software:data_model:opr:type:event:custom_attribut +e" version="1.0"> <name> Service Name</name> <value> IPT</value> </custom_attribute> </custom_attribute_list> <time_created_label> 6/6/2017 03:37:13 PM</time_created_label> <time_changed_label> 6/20/2017 10:37:20 AM</time_changed_label> <time_received_label> 6/20/2017 10:37:20 AM</time_received_label> <time_first_received_label> 6/6/2017 03:37:17 PM</time_first_received_label> </event> </event_list>
      Suggested code @haukex
      #!/usr/bin/perl use warnings; use strict; use XML::XPath; my $file = 'C:/Users/snehit.rahate/Perl/events.xml'; my $xpath = q{//custom_attribute_list/custom_attribute[name='Service N +ame']/value}; # return no result my $xp = XML::XPath->new(filename=>$file); my $nodeset = $xp->find($xpath); for my $node ($nodeset->get_nodelist) { print " XML::XPath: ",$node->string_value,"\n"; }
      I want to concatenate service name and slb_ssrid into one value $appname as shown in below.xml .But not able to fetch the value of tag <name> Service Name</name> my $appname = IPT(957) Please suggest and correct me i am wrong. Thanks a Ton !

        Note that whitespace is significant, and the text content of the node is not 'Service Name', but "\nService Name". One quick way to fix this is by changing your XPath expression to q{//custom_attribute_list/custom_attribute[normalize-space(name)='Service Name']/value}. Since your question is more about XML and XPath than Perl, I recommend you familiarize yourself with those some more, for example at w3schools.