简体   繁体   English

如何获得两个 xpath 节点集的交集

[英]How to get the intersection of two xpath node sets

To get a union of two different node sets I can do the following using the |要获得两个不同节点集的联合,我可以使用|执行以下操作separator:分隔器:

node.xpath(
    '(//C:Year[not(@value="2019")]) | (//R:Product[@value="Phone"])'
    , namespaces={'C': 'Columns', 'R': 'Rows'})

Is there a way to get an intersection between the two without knowing the relationship between those two paths (ie, allowing them to be ordered any way).有没有办法在不知道这两条路径之间关系的情况下获得两者之间的交集(即,允许以任何方式对它们进行排序)。 I tried the following:我尝试了以下方法:

node.xpath('(//C:Year[not(@value="2019")]) and (//R:Product[@value="Phone"])', namespaces={'C': 'Columns', 'R': 'Rows'})

But the and seems to return a bool instead of a node set.但是and似乎返回一个bool而不是一个节点集。 What would be the proper way to do this?这样做的正确方法是什么?

I'm not sure a good place to share xml/xpath expressions but you can go here https://extendsclass.com/xpath-tester.html and copy-paste in the following xpath and xml and it should work fine: I'm not sure a good place to share xml/xpath expressions but you can go here https://extendsclass.com/xpath-tester.html and copy-paste in the following xpath and xml and it should work fine:

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>

One possible solution is to 'go back to the root' for each intersection by using ancestor::RootName , so we would have:一种可能的解决方案是使用ancestor::RootName为每个交叉点“回到根”,因此我们将:

//C:Year[not(@value="2019")]/ancestor::Data//R:Product[@value="Phone"]

Is there another way to do this?还有另一种方法可以做到这一点吗?

In XPath 2.0, use the intersect operator.在 XPath 2.0 中,使用intersect运算符。

There's no simple way of doing it in XPath 1.0在 XPath 1.0 中没有简单的方法

I'm wondering though whether you really want the intersection.我想知道你是否真的想要十字路口。 The intersection of a set of C:Year elements with a set off R:Product elements is going to be empty (no element can be a member of both sets -- it can be a C:Year or an R:Product but not both.). The intersection of a set of C:Year elements with a set off R:Product elements is going to be empty (no element can be a member of both sets -- it can be a C:Year or an R:Product but not both .)。

So I suspect that what you want isn't actually the set intersection, but something else.所以我怀疑你想要的实际上不是设定的交叉点,而是别的东西。 But I can't work out what you want from your question.但我无法从你的问题中弄清楚你想要什么。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM