xpath按元素和属性查找节点,其中包含具有特定id的子元素

Posted

技术标签:

【中文标题】xpath按元素和属性查找节点,其中包含具有特定id的子元素【英文标题】:xpath to find node by element and attribute containing a child element with a certain id 【发布时间】:2021-06-14 07:26:32 【问题描述】:

在 c# 中,我试图找到一个 xpath 表达式,它可以让我得到一个 <property> 元素的值,其 id 为 ROBEGIN,其父级为 <option>,并且该父级包含一个子 <property> CEProductID 的 ID 和 5832198a-7cec-ea11-a817-000d3a191efa 的值。我想要得到的期望值是777。这是一个来自大型 xml 文件的 xml 片段:

...
<option id="Whatever">
   <property id="CEProductID">5832198a-7cec-ea11-a817-000d3a191efa</property>
   ...
   <property id="ROBEGIN">777</property>
</option>
...

重要提示:要使&lt;option&gt; 正确匹配,它必须包含上面显示的两个子元素,具有正确的id 属性值和正确的CEProductID 元素值。如果它有一个或另一个匹配 &lt;property&gt; 但不是两者都匹配,则应忽略它。

我尝试了以下(以及它的其他排列)但没有成功:

xmlNode.SelectNodes($"//property[@id='CEProductID']='5832198a-7cec-ea11-a817-000d3a191efa'");

诚然,上面的 c# 代码行(即使它有效)只会让我得到 CEProductID &lt;property&gt; 元素,我可以使用它以编程方式到达父级,然后返回到属性中查看如果&lt;ROBEGIN&gt; 存在,如果存在,则获取该值。但这似乎效率极低,我认为 xpath 比这更强大。

它是怎么做的?

【问题讨论】:

【参考方案1】:

这应该可以满足您的需求:

//property [@id = 'ROBEGIN' and
    parent::option [property
        [@id = 'CEProductID' and text() = '5832198a-7cec-ea11-a817-000d3a191efa' ]]
]/text()

让我们分解一下:

//property 下降到任何名为 property 的节点 [@id='ROBEGIN' 具有此匹配属性 id and parent::option 并有一个名为 option 的父节点 又拥有[property子节点 又具有[@id='CEProductID' 属性 并且该节点的内部文本匹配text()='5832198a-7cec-ea11-a817-000d3a191efa' ]]]/text()回到原来的节点,取内文

结果:

777

【讨论】:

Charlieface,答案很棒,效果很好。感谢您简洁的回复。【参考方案2】:

如果我理解正确,您希望将选项标记与您问题中所述的两个属性进行匹配,然后进入第二个 ROBEGIN 并提取内部 html

//option[property[@id='CEProductID'] and property[@id='ROBEGIN']]/property[@id='ROBEGIN']/text()

# 777

【讨论】:

BcK,看起来是一个很好的答案,但缺少需要成为其中一部分的 guid。所以我支持你,但给了查理正确的答案。非常感谢您的时间和关注。 没问题,我认为这有点不言自明,但你是对的。

以上是关于xpath按元素和属性查找节点,其中包含具有特定id的子元素的主要内容,如果未能解决你的问题,请参考以下文章

XPath/HtmlAgilityPack:如何查找具有属性 (href) 特定值的元素 (a) 并查找相邻的表列?

Xpath:选择除具有特定属性的元素之外的所有元素

按属性查找元素

xpath

C#:XPath 选择具有包含子字符串的属性的节点?

如何在具有 xmlns 属性的 xml 中使用 xpath 获取特定的嵌套元素? [复制]