我在到达正确的xpath来查询来自xml的数据时遇到了问题。我使用XML::LibXML
来执行此操作
<?xml version="1.0" encoding="iso-8859-1"?>
<data>
<header>
<date>2016-08-07</date>
<name>Indices Composites</name>
<version>1.1a</version>
</header>
<row>
<CompositePrice>1.010227784212584</CompositePrice>
<CompositeSpread>0.002568273865609903</CompositeSpread>
<Date>2016-08-05</Date>
<Depth>4</Depth>
<Heat>0.0201994587386602</Heat>
<IndexID>ITRAXX-SOVXWES8V1-5Y</IndexID>
<Maturity>2017-12-20</Maturity>
<ModelPrice>1.0103988929051526</ModelPrice>
<ModelSpread>0.002445016658588964</ModelSpread>
<Name>iTraxx SovX Westn Europe</Name>
<OnTheRun>Y</OnTheRun>
<REDCode>5C769MAO9</REDCode>
<RequestKey>iTraxx SovX Westn Europe|5Y|Y</RequestKey>
<Series>8</Series>
<ShortName></ShortName>
<Term>5Y</Term>
<Version>1</Version>
</row>
<row>
<CompositePrice>1.0208723593556004</CompositePrice>
<CompositeSpread>0.006539233068666665</CompositeSpread>
<Date>2016-08-05</Date>
<Depth>3</Depth>
<Heat>0.0307106033333336</Heat>
<IndexID>ITRAXX-SOVXWES8V1-10Y</IndexID>
<Maturity>2022-12-20</Maturity>
<ModelPrice>1.0219657857189512</ModelPrice>
<ModelSpread>0.006361337372712667</ModelSpread>
<Name>iTraxx SovX Westn Europe</Name>
<OnTheRun>Y</OnTheRun>
<REDCode>5C769MAO9</REDCode>
<RequestKey>iTraxx SovX Westn Europe|10Y|Y</RequestKey>
<Series>8</Series>
<ShortName></ShortName>
<Term>10Y</Term>
<Version>1</Version>
</row>
</data>
我需要根据某些标签的值进行过滤。代码如下所示。
my $parser = XML::LibXML->new;
my $doc = $parser->parse_file($inputFile);
my @nodes = $doc->findnodes("/data/row/Name[text()='iTraxx SovX Westn Europe']/../Term[text()='5Y']/../OnTheRun[text()='Y']");
print "@nodes \n";
我得到的输出是
<OnTheRun>Y</OnTheRun>
而我希望得到满足条件的整个节点。
XPath表达式就在这里吗?
答案 0 :(得分:3)
XPath表达式非常类似于Linux文件路径。如果从所写的内容中删除所有谓词,则得到
/data/row/Name/../Term/../OnTheRun
您可以在此处看到,从row
元素开始,您将升入Name
并返回一个级别,然后返回Term
并返回一个级别,最后进入OnTheRun
,其中表达式停止
这就是为什么您只看到OnTheRun
元素的值,一个简单的修复方法是添加另一个..
路径步骤以返回到您的row
元素想要访问
这个XPath表达式工作正常
/data/row/Name[text()='iTraxx SovX Westn Europe']/../Term[text()='5Y']/../OnTheRun[text()='Y']/..
但阅读
非常尴尬我认为最好的方法是将多个谓词应用到主/data/row
选择器,就像这样
/data/row[Name="iTraxx SovX Westn Europe"][Term="5Y"][OnTheRun="Y"]
这是一个完整的程序,用它来处理您的样本数据
use strict;
use warnings 'all';
use open IO => ":encoding(iso-8859-1)";
use XML::LibXML;
my $doc = XML::LibXML->load_xml( location => 'indices_composites.xml' );
my @nodes = $doc->findnodes('/data/row[Name="iTraxx SovX Westn Europe"][Term="5Y"][OnTheRun="Y"]');
printf "%d node%s found:\n\n", scalar @nodes, @nodes == 1 ? '' : 's';
print $nodes[0], "\n";
1 node found:
<row>
<CompositePrice>1.010227784212584</CompositePrice>
<CompositeSpread>0.002568273865609903</CompositeSpread>
<Date>2016-08-05</Date>
<Depth>4</Depth>
<Heat>0.0201994587386602</Heat>
<IndexID>ITRAXX-SOVXWES8V1-5Y</IndexID>
<Maturity>2017-12-20</Maturity>
<ModelPrice>1.0103988929051526</ModelPrice>
<ModelSpread>0.002445016658588964</ModelSpread>
<Name>iTraxx SovX Westn Europe</Name>
<OnTheRun>Y</OnTheRun>
<REDCode>5C769MAO9</REDCode>
<RequestKey>iTraxx SovX Westn Europe|5Y|Y</RequestKey>
<Series>8</Series>
<ShortName/>
<Term>5Y</Term>
<Version>1</Version>
</row>