Search code examples
c#xpathor-operator

Sort XPath Or Operator Results


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.


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();