xpath选择具有给定祖先属性的所有叶节点

时间:2015-03-12 14:56:16

标签: c# xml xpath

我有一批xmls,其中每个标签都有一个属性isOptional。这种xml的一个例子是

<node1 isOptional="False">
    <node2 isOptional="True">
        <node22 isOptional="False">
            <node3 isOptional="False">text4</node3>
        </node22>
    </node2>
    <node4 isOptional="False">
        <node5 isOptional="False">
            <node6 isOptional="True">text3</node6>
            <node7 isOptional="False">
                <node8 isOptional="True">text2</node8>
                <node9 isOptional="False">text1</node9>
            </node7>
        </node5>
    </node4>
</node1>

我需要编写xpath来选择没有@isOptional="True"的ancessors的所有叶子节点。对于此示例,结果应为:

       <node9 isOptional="False">text1</node9>

其实我需要这样的东西:

//*[not(*) and @isOptional="False" and count(ancestor::*[@isOptional = "True"] = 0)]

你能帮我找到正确的xpath吗?

2 个答案:

答案 0 :(得分:1)

像这样的XPath应该可以工作:

//*[not(child::*) and not(ancestor-or-self::*[@isOptional = 'True'])]

答案 1 :(得分:1)

我想你忘了提一个额外的要求。你说的是什么:

  

我需要编写xpath来选择没有@isOptional="True"

的所有叶子节点

将映射到以下XPath表达式:

//*[not(*) and not(ancestor::*[@isOptional = 'True'])]
^^^                                                           "all"
   ^^^^^^^                                                    "leaf nodes"
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        "no ancestor where
                                                              @isOptional equals 'True'"

会产生(个别结果由------分隔):

<node6 isOptional="True">text3</node6>
-----------------------
<node8 isOptional="True">text2</node8>
-----------------------
<node9 isOptional="False">text1</node9>

但我假设您要添加:此外,目标节点的isOptional属性也不能设置为True。这导致以下路径表达式,已由potame正确建议:

//*[not(*) and not(ancestor-or-self::*[@isOptional = 'True'])]

,唯一的结果是

<node9 isOptional="False">text1</node9>

因为现在XPath表达式包含ancestor-or-self::轴,其中包含上下文节点本身。