C# 如何为XML创建XPath?

C# 如何为XML创建XPath?,c#,xml,xpath,xml-parsing,linq-to-xml,C#,Xml,Xpath,Xml Parsing,Linq To Xml,我有一个Xml文件,我想在其中使用基于XPath的过滤器。我试过很多例子,但没有一个对我有帮助。毫无疑问,我犯了一些错误。 我是XPath新手,请帮助我找到解决方案 <PeopleBatch Counter="3"> <Citriz ID="1d9a88fe-f9cc-4add-b6d1-01e41c561bfb" mVersion="1.0.0" mSequence="1" pVersion="0.0.1" xmlns="http://Citriz/Schemas">

我有一个Xml文件,我想在其中使用基于XPath的过滤器。我试过很多例子,但没有一个对我有帮助。毫无疑问,我犯了一些错误。 我是XPath新手,请帮助我找到解决方案

<PeopleBatch Counter="3">
<Citriz ID="1d9a88fe-f9cc-4add-b6d1-01e41c561bfb" mVersion="1.0.0" mSequence="1" pVersion="0.0.1" xmlns="http://Citriz/Schemas">
    <People Action="U" Status="CD" PeopleID="1" PeopleShortName="Billy" PeopleLongName="Billy Smith" PeopleTypeCode="Commercial" CountryCode="USA" PeopleStatus="Current">
            <PeopleRole Action="U" Status="CD" ID="1" CustomerRoleShortName="Billy" CustomerRoleLongName="Billy Smith" TypeCode="OUTS">
                    <SendRole RoleType="N" ActiveRole="Y"/>
            </PeopleRole>
    </People>
</Citriz>
<Citriz ID="1d9a88fe-f9cc-4add-b6d1-01e41c561bfc" mVersion="1.0.0" mSequence="2" pVersion="0.0.1" xmlns="http://Citriz/Schemas">
    <People Action="U" Status="CD" PeopleID="2" PeopleShortName="Carl" PeopleLongName="Carl Thomas" PeopleTypeCode="Commercial" CountryCode="USA" PeopleStatus="Current">
            <PeopleRole Action="U" Status="CD" ID="2" CustomerRoleShortName="Carl" CustomerRoleLongName="Carl Thomas" TypeCode="INSS">
                    <SendRole RoleType="N" ActiveRole="Y"/>
            </PeopleRole>
    </People>
</Citriz>   
<Citriz ID="1d9a88fe-f9cc-4add-b6d1-01e41c561bfd" mVersion="1.0.0" mSequence="3" pVersion="0.0.1" xmlns="http://Citriz/Schemas">
    <People Action="U" Status="CD" PeopleID="3" PeopleShortName="Ryan" PeopleLongName="Ryan Black" PeopleTypeCode="Commercial" CountryCode="USA" PeopleStatus="Current">
            <PeopleRole Action="U" Status="CD" ID="3" CustomerRoleShortName="Ryan" CustomerRoleLongName="Ryan Black" TypeCode="INSS">
                    <SendRole RoleType="N" ActiveRole="Y"/>
            </PeopleRole>
    </People>
</Citriz>   


我需要所有那些子节点属性包含TypeCode=“INSS”此值的“Citriz”节点。或者,如果还有其他好方法,请向我推荐。

鉴于您使用的是LINQ to XML,我不会首先使用XPath。我会使用:

XNamespace ns = "http://Citriz/Schemas";
var nodes = doc.Descendants(ns + "Citriz")
               .Where(x => x.Descendants()
                            .Any(y => (string) x.Attribute("TypeCode") == "INSS"));
或者,如果总是将
PeopleRole
元素放在
People
Citriz
中(每个级别只有一个元素):


我确信在XPath中可以明智地做到这一点,但我个人认为LINQ to XML更简单,可以将数据部分(元素名称、期望值等)与“代码”部分分开(“我正在寻找后代”或“我正在寻找属性值”)

可以考虑XPath等同于在文件系统中导航目录树。向xpath查询添加额外的“目录”将使您更深入地了解DOM树

//PeopleRole[@TypeCode="inss"]/../..

将查找所有类型为PeopleRole的节点,其TypeCode属性等于'inss',然后在树中向上移动到级别,返回包含匹配PeopleRole的
节点

我认为您在Xml名称空间方面有问题

XNamespace ns = "http://Citriz/Schemas";
var peopleRole = XDocument.Parse(xml)
                    .Descendants(ns + "PeopleRole")
                    .Where(p => p.Attribute("TypeCode").Value == "INSS")
                    .ToList();

如果要计算XNode中的XPath表达式,可以使用
XPathSelectElements
扩展方法。谢谢你的回答。双向都不返回任何值。毫无疑问,我犯了任何错误或遗漏了什么。我还需要一些额外的东西吗?@PankajMishra:这段代码也因为名称空间而失败-我没有发现名称空间。我已经正确地修复了代码。非常感谢您的回答,但它不会同时返回两个节点。@PankajMishra我假设您想要第一个节点。只需将
第一个
替换为
其中
。仅此而已。我更新了答案。
XNamespace ns = "http://Citriz/Schemas";
var peopleRole = XDocument.Parse(xml)
                    .Descendants(ns + "PeopleRole")
                    .Where(p => p.Attribute("TypeCode").Value == "INSS")
                    .ToList();