1

Referencing the two questions here and here
I would like to sort on child nodes as well, but resetting for each "outer" node.
So:

<Root>
    <I aa="1">
        <s aa="3"/>
        <s aa="1"/>
        <s aa="2"/>
    </I>
    <I aa="5">
        <s aa="3"/>
        <s aa="1"/>
        <s aa="2"/>
    </I>
    <I aa="3">
        <s aa="3"/>
        <s aa="1"/>
        <s aa="2"/>
    </I>
    <I aa="4">
        <s aa="3"/>
        <s aa="1"/>
        <s aa="2"/>
    </I>
</Root>

Would become:

<Root>
    <I aa="1">
        <s aa="1"/>
        <s aa="2"/>
        <s aa="3"/>
    </I>
    <I aa="3">
        <s aa="1"/>
        <s aa="2"/>
        <s aa="3"/>
    </I>
    <I aa="4">
        <s aa="1"/>
        <s aa="2"/>
        <s aa="3"/>
    </I>
    <I aa="5">
        <s aa="1"/>
        <s aa="2"/>
        <s aa="3"/>
    </I>
</Root>

I tried different variations of the XDocument sorting, but I cannot get the syntax right.
Hoping someone can help, or provide me with an idea.

0

2 Answers 2

1

You need some recursion here - each element needs to be cloned and its child elements sorted by the aa attribute. A method to do that might look like this:

private static XElement CopyAndSort(XElement e)
{
    var elements = e.Elements()
        .OrderBy(x => (string)x.Attribute("aa"))
        .Select(CopyAndSort);
    return new XElement(e.Name, e.Attributes(), elements);
}

If you then call that with your Root element, you will get back a new Root element with all its children sorted (and their children sorted, and so on).

See this fiddle for a working demo.

Sign up to request clarification or add additional context in comments.

1 Comment

Amazing! Thanks, that was just what I was needed. I was trying to see some way around foreaching it, but the recursive version is brilliant. Thank so much :-)
0

In my case, my XML was also containing string contents at the lowest level of the nodes. For this, I had to slightly amend the sorting code, otherwise that bit would be eliminated:

private static XElement CopyAndSort(XElement e)
{
    if (e.HasElements)
    {
        var elements = e.Elements()
            .OrderBy(keySelector: x => (string?)x.Attribute("name"))
            .Select(CopyAndSort);
        return new XElement(e.Name, e.Attributes(), elements);
    }
    return e;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.