如何在C#中使用XPath检索最后一个节点?

时间:2011-08-24 17:17:39

标签: c# xml xpath

我有以下部分xml文件。

<UN N="@U1">
    <DT N="24/06/2011">
        <PN N="@P1">
            <TM N="02:24:11">
                <JB T="GP">
                    <A>notepad</A>
                    <Z>Notepad</Z>
                    <N>Untitled - Notepad</N>
                    <J>1;0;1;1;0;0</J>
                    <C>0.00500;0.09500;0.03500</C>
                    <S>1;0;1;1</S>
                    <P>0;0</P>
                    <F>0</F>
                </JB>
            </TM>
        </PN>
    </DT>

    <DT N="23/06/2011">
        <PN N="@P1">
            <TM N="02:38:49">
                <JB T="PAGP">
                    <A>notepad</A>
                    <Z>Notepad</Z>
                    <N>Untitled - Notepad</N>
                    <J>1;1;1;1;0;1</J>
                    <C>0.00500;0.09500;0.03500</C>
                    <S>1;1;0;0</S>
                    <P>1;1</P>
                    <F>0</F>
                </JB>
            </TM>               
        </PN>
    </DT>

    .....
    .....

</UN>

我需要得到PN N = @ P1的最后一个节点。

示例查询将不胜感激。

提前致谢。

2 个答案:

答案 0 :(得分:6)

XPath操作:

"/UN/DT[PN/@N='@p1'][last()]"

将返回PN=@p1的最后一个 DT 节点。

答案 1 :(得分:5)

last() XPath函数可用于查找节点集的最后一个。因此,具有值<PN>的attribyte N的最后一个@P1节点将是:

//PN[@N='@P1'][position() = last()]

.NET代码将取决于您使用的XML API:XmlDocumentXPathDocument或LINQ to XML(XDocument)。 (使用XmlReader的方法是加载到三者之一,然后使用它。)

编辑(基于评论)要返回上一个<F>的{​​{1}}后代,其属性如上所述,其中<PN>是{xDoc的实例1}}:

XmlDocument

编辑#2(基于其他评论):要返回最后 var foundNode = xDoc.SelectSingleNode("//PN[@N='@P1'][position() = last()]/TM/JB/F"); ,其中每个<PN>可以包含多个<DT>所有<DT>元素中的元素 1

使用一些更好的示例XML(见下文)测试它,使用XmlElement.SelectNodes然后迭代返回的节点集显示正在找到正确的节点,它不是第一个,因此不会返回<DT>。这是线索:SelectSingleNode谓词正在每个last()匹配中应用。只需快速更改优先级即可:

//PN[@N='@P1']

1 为了将来参考,如果可能有多个元素,则在样本中至少显示两个,否则读者将只假设单个实例。同时剥离不需要的所有节点(如孩子):

我用于测试的示例XML(添加了x属性,以便在测试时轻松识别所选元素):

(//PN[@N='@P1'])[last()]