xpath选择其父节点类型不同的子节点

时间:2018-09-04 20:29:16

标签: xml xpath

我为可能引起误解的标题表示歉意,但我不知道该如何措辞。

我有一个巨大的xml文件,其中包含许多元素,并且我需要获取某个元素(名称为w:r),但前提是该元素不在另一个名称为w:r的元素内

例如:

<w:r>
    test
</w:r>

应选择一个元素

<w:r>
    <w:r>
        test
    </w:r>
</w:r>

还应仅选择一个元素(外部元素),而不是两个。

我当前的解决方案是://*[local-name()='r'],但是它为第二个示例选择了两个元素(一个是外部元素,另一个是内部元素)

1 个答案:

答案 0 :(得分:1)

您可以使用以下XPath表达式提取外部w:r元素:

//*[local-name()='r' and not(parent::*[local-name()='r'])]

对于以下XML(用于测试):

<?xml version='1.0' encoding='utf-8'?>
<root xmlns:w="xxx">
    <w:r t="c">
        test
    </w:r>  
    <w:r t="d">
        <w:r t="h">
            test
        </w:r>
    </w:r>
    <w:r t="e">
        <a>
            <b>
                <c>...
                    <w:r t="i">Something</w:r>
                    ...
                </c>
            </b>
        </a>
    </w:r>
</root>

输出为:

<w:r xmlns:w="xxx" t="c"/>  
<w:r xmlns:w="xxx" t="d"/>
<w:r xmlns:w="xxx" t="e"/>

这意味着所有外部w:r元素都由表达式选择。


如果您想考虑所有父母,而不仅仅是直接父母,则可以使用ancestor::轴,如下所示:

//*[local-name()='r' and not(ancestor::*[local-name()='r'])]

对于示例XML,结果相同,但是语义不同。