Question

Given the following XML:

<xml>
    <Table>
        <Product>
            <CaseName>Test 1</CaseName>
            <Beta>banana</Beta>
            <Alpha>apple</Alpha>
            <Delta>dates</Delta>
            <Chi>chiku</Chi>
        </Product>
        <Product>
            <CaseName>Test 2</CaseName>
            <Beta>borange</Beta>
            <Alpha>ared</Alpha>
            <Delta>dblue</Delta>
            <Chi>cgreen</Chi>
        </Product>
    </Table>
</xml>

I would like to use XPath and the "or" operator to dictate the order the nodes under Product are returned, but regardless of the XPath statement that I use, the query results are always returned in the order of the original XML. For example, the following XPath statements:

  1. //Delta | //CaseName | //Beta
  2. //CaseName | //Beta | //Delta
  3. //Delta | //Beta | //CaseName

All return nodes in the following order: CaseName, Beta, Delta, CaseName, Beta, Delta. This order matches the original XML node structure. What XPath statement can I use with the "or" operator to return the nodes in the order that I desire?

I'm using C# as my development environment.

Was it helpful?

Solution

If XPath is not a must, you can use LinqToXml to sort the elements

XDocument xDoc = XDocument.Parse(xmlstring); //or XDocument.Load(filename)
var products = xDoc.Descendants("Product")
                .Select(p => p.Elements().OrderBy(e => e.Name.LocalName).ToList())
                .ToList();

Or maybe something like this

List<string> names = new List<string>{ "CaseName", "Beta", "Delta" };

XDocument xDoc = XDocument.Parse(xml);
var products = xDoc.Descendants("Product")
                .Select(p => p.Elements()
                              .Where(e => names.Contains(e.Name.LocalName))
                              .OrderBy(e => names.IndexOf(e.Name.LocalName)).ToList())
                .ToList();

OTHER TIPS

In terms of XPath, you need to understand that XPath 1.0 only knows unordered node sets so with //foo | //bar you get a set of foo and bar element nodes. Most implementations then return the result in document order.

If you want to be able to define the order you need to use XPath 2.0 (or XQuery 1.0) where the data model knows ordered sequences of nodes (and atomic items), there you could use the comma operator , as in //foo, //bar to get a sequence of foo and bar element nodes. However the Microsoft .NET framework class library does not come with an XPath 2.0 implementation, you would need to use to switch to third party solutions like XmlPrime or the .NET version of Saxon 9.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top