Perl 使用XML::LibXML时XML的正确XPath表达式

Perl 使用XML::LibXML时XML的正确XPath表达式,perl,xpath,Perl,Xpath,我遇到了一个问题,那就是如何找到正确的xpath来从xml查询数据。我过去经常这样做 XML 我得到的输出是 <OnTheRun>Y</OnTheRun> Y 而我想得到满足条件的整个节点 XPath表达式就在这里吗?XPath表达式非常类似于Linux文件路径。如果从所编写的内容中删除所有谓词,则会得到 /data/row/Name/。/Term/。/OnTheRun 您可以在这里看到,从行元素,您将下降到名称并返回到一个级别,然后进入术语并返回到一个级别,最后进

我遇到了一个问题,那就是如何找到正确的xpath来从xml查询数据。我过去经常这样做

XML 我得到的输出是

<OnTheRun>Y</OnTheRun>
Y
而我想得到满足条件的整个节点


XPath表达式就在这里吗?

XPath表达式非常类似于Linux文件路径。如果从所编写的内容中删除所有谓词,则会得到

/data/row/Name/。/Term/。/OnTheRun
您可以在这里看到,从
元素,您将下降到
名称
并返回到一个级别,然后进入
术语
并返回到一个级别,最后进入
OnTheRun
,表达式在此停止

这就是为什么您只看到
OnTheRun
元素的值,一个简单的修复方法是附加另一个
路径步骤以返回到要访问的
元素

这个XPath表达式工作得很好

/data/row/Name[text()='iTraxx SovX Westn Europe']/../Term[text()='5Y']/../OnTheRun[text()='Y']/../。。
但是阅读起来很尴尬

我认为最简单的方法是对主
/data/row
选择器应用多个谓词,如下所示

/data/row[Name=“iTraxx-SovX-Westn-european”][Term=“5Y”][OnTheRun=“Y”]
这里有一个完整的程序,使用它来处理您的样本数据

使用严格;
使用“全部”警告;
使用开放IO=>“:编码(iso-8859-1)”;
使用XML::LibXML;
my$doc=XML::LibXML->load_XML(位置=>'index_composites.XML');
my@nodes=$doc->findnodes('/data/row[Name=“iTraxx-SovX-Westn-Europe”][Term=“5Y”][OnTheRun=“Y”]”);
printf“%d个节点%s已找到:\n\n”,标量@nodes,@nodes==1?“”:s′;
打印$nodes[0],“\n”;
输出 找到
1个节点:
1.010227784212584
0.002568273865609903
2016-08-05
4.
0.0201994587386602
ITRAXX-SOVXWES8V1-5Y
2017-12-20
1.0103988929051526
0.002445016658588964
iTraxx SovX西欧
Y
5C769MAO9
iTraxx SovX西欧| 5Y | Y
8.
5Y
1.

示例数据中的
名称
元素是相同的,它们中的任何一个都与XPath表达式匹配。我的错。在我编辑之前正在修改代码。如果现在更新了正确的值而不是
Name/text()=''.''.'
,我建议使用
Name='.''.'.
来比较元素的属性,而不是它的第一个文本子元素的内容。我还将使用一个谓词,将多个表达式
组合在一起:
/data/row[Name=''…'和Term=''…'和OnTheRun='Y']
。我认为它更清晰一点,性能也应该稍微好一点。谢谢博罗丁和恩韦尔霍夫。。这是非常有用的!!我还刚刚意识到我可以在@nwellnhof测试我的xpath:我同意在这种情况下最好省略
text()
,但是使用
是一种装饰性的偏好。添加更多的谓词可以节省几个字符,我认为这会使它更具可读性。
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>