Pankaj Mishra
Pankaj Mishra

Reputation: 20358

How To Create XPath for XML?

I have one Xml file in which i want to make filter based on XPath. I tried lot of examples none of them are helping No doubt I am doing some mistake. I am new in XPath please help me to find the solution.

<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>   

I need all those "Citriz" node which child node attribute contains TypeCode="INSS" this value. Or Suggest me if there is any other good way.

Upvotes: 2

Views: 198

Answers (3)

Jon Skeet
Jon Skeet

Reputation: 1503689

Given that you're using LINQ to XML, I wouldn't use XPath to start with. I'd use:

XNamespace ns = "http://Citriz/Schemas";
var nodes = doc.Descendants(ns + "Citriz")
               .Where(x => x.Descendants()
                            .Any(y => (string) x.Attribute("TypeCode") == "INSS"));

Or if it's always going to be the PeopleRole element inside People inside Citriz (with just a single element at each level):

XNamespace ns = "http://Citriz/Schemas";
var nodes = doc.Descendants(ns + "Citriz")
               .Where(x => (string) x.Element(ns + "People")
                                     .Element(ns + "PeopleRole")
                                     .Attribute("TypeCode") == "INSS"));

I'm sure this can be done sensibly in XPath, but personally I find LINQ to XML simpler, in terms of separating the data parts (names of elements, expected values etc) separate from the "code" parts ("I'm looking for descendants" or "I'm looking for an attribute value").

Upvotes: 6

I4V
I4V

Reputation: 35363

I think you have problem with Xml namespaces

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

Upvotes: 1

Marc B
Marc B

Reputation: 360872

You can consider XPath to be the equivalent of navigating a directory tree in a filesystem. Adding extra "directories" to the xpath query takes you deeper into the DOM tree.

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

would find all nodes of type PeopleRole, with the TypeCode attribute equal to 'inss', then move up to levels in the tree, returning the <Citriz> node that contains the matched PeopleRoles

Upvotes: 0

Related Questions