如何获取两个xpath节点集的交集
How to get the intersection of two xpath node sets
要获得两个不同节点集的并集,我可以使用 |
分隔符执行以下操作:
node.xpath(
'(//C:Year[not(@value="2019")]) | (//R:Product[@value="Phone"])'
, namespaces={'C': 'Columns', 'R': 'Rows'})
有没有办法在不知道这两条路径之间的关系(即允许它们以任何方式排序)的情况下获得两者之间的交集。我尝试了以下方法:
node.xpath('(//C:Year[not(@value="2019")]) and (//R:Product[@value="Phone"])', namespaces={'C': 'Columns', 'R': 'Rows'})
但是and
似乎return一个bool
而不是一个节点集。执行此操作的正确方法是什么?
我不确定分享 xml/xpath 表达式的好地方,但你可以去这里 https://extendsclass.com/xpath-tester.html 并在下面的 xpath 和 xml 中复制粘贴,它应该可以正常工作:
Expression: //C:Year[not(@value="2019")] | //R:Product[@value="Phone"]
XML: <Data xmlns:R="Rows" xmlns:C="Columns" xmlns:V="Values"><R:ProductGroup value="Electronics"><R:Product value="Computer"><C:Year value="2018"><V:SumOfRevenue value="104"/><V:SumOfUnits value="3"/></C:Year><C:Year value="2019"><V:SumOfRevenue value="82"/><V:SumOfUnits value="9"/></C:Year><C:Year value="(all)"><V:SumOfRevenue value="186"/><V:SumOfUnits value="12"/></C:Year></R:Product><R:Product value="Phone"><C:Year value="2018"><V:SumOfRevenue value="102"/><V:SumOfUnits value="4"/></C:Year><C:Year value="2019"><V:SumOfRevenue value="99"/><V:SumOfUnits value="12"/></C:Year><C:Year value="(all)"><V:SumOfRevenue value="201"/><V:SumOfUnits value="16"/></C:Year></R:Product><R:Product value="(all)"><C:Year value="2018"><V:SumOfRevenue value="206"/><V:SumOfUnits value="7"/></C:Year><C:Year value="2019"><V:SumOfRevenue value="181"/><V:SumOfUnits value="21"/></C:Year><C:Year value="(all)"><V:SumOfRevenue value="387"/><V:SumOfUnits value="28"/></C:Year></R:Product></R:ProductGroup><R:ProductGroup value="Media"><R:Product value="Movies"><C:Year value="2018"><V:SumOfRevenue value="25"/><V:SumOfUnits value="12"/></C:Year><C:Year value="2019"><V:SumOfRevenue value="26"/><V:SumOfUnits value="13"/></C:Year><C:Year value="(all)"><V:SumOfRevenue value="51"/><V:SumOfUnits value="25"/></C:Year></R:Product><R:Product value="Theater"><C:Year value="2018"><V:SumOfRevenue value="17"/><V:SumOfUnits value="3"/></C:Year><C:Year value="2019"><V:SumOfRevenue value="20"/><V:SumOfUnits value="6"/></C:Year><C:Year value="(all)"><V:SumOfRevenue value="37"/><V:SumOfUnits value="9"/></C:Year></R:Product><R:Product value="(all)"><C:Year value="2018"><V:SumOfRevenue value="42"/><V:SumOfUnits value="15"/></C:Year><C:Year value="2019"><V:SumOfRevenue value="46"/><V:SumOfUnits value="19"/></C:Year><C:Year value="(all)"><V:SumOfRevenue value="88"/><V:SumOfUnits value="34"/></C:Year></R:Product></R:ProductGroup><R:ProductGroup value="(all)"><R:Product value="(all)"><C:Year value="2018"><V:SumOfRevenue value="248"/><V:SumOfUnits value="22"/></C:Year><C:Year value="2019"><V:SumOfRevenue value="227"/><V:SumOfUnits value="40"/></C:Year><C:Year value="(all)"><V:SumOfRevenue value="475"/><V:SumOfUnits value="62"/></C:Year></R:Product></R:ProductGroup></Data>
一个可能的解决方案是使用 ancestor::RootName
为每个交叉路口 'go back to the root',因此我们将有:
//C:Year[not(@value="2019")]/ancestor::Data//R:Product[@value="Phone"]
还有其他方法吗?
在 XPath 2.0 中,使用 intersect
运算符。
在 XPath 1.0 中没有简单的方法
我想知道你是否真的想要这个路口。一组 C:Year
元素与一组 R:Product
元素的交集将是空的(没有元素可以是两个集合的成员——它可以是 C:Year
或R:Product
但不是两者。)。
所以我怀疑你想要的实际上不是集合交集,而是其他东西。但是我无法从你的问题中得出你想要的。
要获得两个不同节点集的并集,我可以使用 |
分隔符执行以下操作:
node.xpath(
'(//C:Year[not(@value="2019")]) | (//R:Product[@value="Phone"])'
, namespaces={'C': 'Columns', 'R': 'Rows'})
有没有办法在不知道这两条路径之间的关系(即允许它们以任何方式排序)的情况下获得两者之间的交集。我尝试了以下方法:
node.xpath('(//C:Year[not(@value="2019")]) and (//R:Product[@value="Phone"])', namespaces={'C': 'Columns', 'R': 'Rows'})
但是and
似乎return一个bool
而不是一个节点集。执行此操作的正确方法是什么?
我不确定分享 xml/xpath 表达式的好地方,但你可以去这里 https://extendsclass.com/xpath-tester.html 并在下面的 xpath 和 xml 中复制粘贴,它应该可以正常工作:
Expression: //C:Year[not(@value="2019")] | //R:Product[@value="Phone"]
XML: <Data xmlns:R="Rows" xmlns:C="Columns" xmlns:V="Values"><R:ProductGroup value="Electronics"><R:Product value="Computer"><C:Year value="2018"><V:SumOfRevenue value="104"/><V:SumOfUnits value="3"/></C:Year><C:Year value="2019"><V:SumOfRevenue value="82"/><V:SumOfUnits value="9"/></C:Year><C:Year value="(all)"><V:SumOfRevenue value="186"/><V:SumOfUnits value="12"/></C:Year></R:Product><R:Product value="Phone"><C:Year value="2018"><V:SumOfRevenue value="102"/><V:SumOfUnits value="4"/></C:Year><C:Year value="2019"><V:SumOfRevenue value="99"/><V:SumOfUnits value="12"/></C:Year><C:Year value="(all)"><V:SumOfRevenue value="201"/><V:SumOfUnits value="16"/></C:Year></R:Product><R:Product value="(all)"><C:Year value="2018"><V:SumOfRevenue value="206"/><V:SumOfUnits value="7"/></C:Year><C:Year value="2019"><V:SumOfRevenue value="181"/><V:SumOfUnits value="21"/></C:Year><C:Year value="(all)"><V:SumOfRevenue value="387"/><V:SumOfUnits value="28"/></C:Year></R:Product></R:ProductGroup><R:ProductGroup value="Media"><R:Product value="Movies"><C:Year value="2018"><V:SumOfRevenue value="25"/><V:SumOfUnits value="12"/></C:Year><C:Year value="2019"><V:SumOfRevenue value="26"/><V:SumOfUnits value="13"/></C:Year><C:Year value="(all)"><V:SumOfRevenue value="51"/><V:SumOfUnits value="25"/></C:Year></R:Product><R:Product value="Theater"><C:Year value="2018"><V:SumOfRevenue value="17"/><V:SumOfUnits value="3"/></C:Year><C:Year value="2019"><V:SumOfRevenue value="20"/><V:SumOfUnits value="6"/></C:Year><C:Year value="(all)"><V:SumOfRevenue value="37"/><V:SumOfUnits value="9"/></C:Year></R:Product><R:Product value="(all)"><C:Year value="2018"><V:SumOfRevenue value="42"/><V:SumOfUnits value="15"/></C:Year><C:Year value="2019"><V:SumOfRevenue value="46"/><V:SumOfUnits value="19"/></C:Year><C:Year value="(all)"><V:SumOfRevenue value="88"/><V:SumOfUnits value="34"/></C:Year></R:Product></R:ProductGroup><R:ProductGroup value="(all)"><R:Product value="(all)"><C:Year value="2018"><V:SumOfRevenue value="248"/><V:SumOfUnits value="22"/></C:Year><C:Year value="2019"><V:SumOfRevenue value="227"/><V:SumOfUnits value="40"/></C:Year><C:Year value="(all)"><V:SumOfRevenue value="475"/><V:SumOfUnits value="62"/></C:Year></R:Product></R:ProductGroup></Data>
一个可能的解决方案是使用 ancestor::RootName
为每个交叉路口 'go back to the root',因此我们将有:
//C:Year[not(@value="2019")]/ancestor::Data//R:Product[@value="Phone"]
还有其他方法吗?
在 XPath 2.0 中,使用 intersect
运算符。
在 XPath 1.0 中没有简单的方法
我想知道你是否真的想要这个路口。一组 C:Year
元素与一组 R:Product
元素的交集将是空的(没有元素可以是两个集合的成员——它可以是 C:Year
或R:Product
但不是两者。)。
所以我怀疑你想要的实际上不是集合交集,而是其他东西。但是我无法从你的问题中得出你想要的。