Search code examples
c#xmllinqsortingxmldocument

Sorting all the XmlNode in XmlDocument


I have a XML file (XmlDocument) containing data as shown below

<?xml version="1.0" encoding="utf-8"?>
<xml>
    <transactions>
        <transaction date="03022014" type="document">
            <document name="Page1">
                <data>
                    <document>
                        <attribute name="Position" value="4"/>
                        <attribute name="qty" value="1"/>
                        <attribute name="number" value="1202"/>
                    </document>
                    <document>
                        <attribute name="Position" value="3"/>
                        <attribute name="qty" value="1"/>
                        <attribute name="number" value="1203"/>
                    </document>
                    <document>
                        <attribute name="Position" value="2"/>
                        <attribute name="qty" value="1"/>
                        <attribute name="number" value="1205"/>
                    </document>
                    <document>
                        <attribute name="Position" value="1"/>
                        <attribute name="qty" value="1"/>
                        <attribute name="number" value="1206"/>
                    </document>
                </data>
            </document>
        </transaction>
    </transactions>
</xml>

I want to sort the <document> element by "Position". It should be as follows

<?xml version="1.0" encoding="utf-8"?>
<xml>
    <transactions>
        <transaction date="03022014" type="document">
            <document name="Page1">
                <data>
            <document>
                        <attribute name="Position" value="1"/>
                        <attribute name="qty" value="1"/>
                        <attribute name="number" value="1206"/>
                    </document>
                <document>
                        <attribute name="Position" value="2"/>
                        <attribute name="qty" value="1"/>
                        <attribute name="number" value="1205"/>
                    </document>
                <document>
                        <attribute name="Position" value="3"/>
                        <attribute name="qty" value="1"/>
                        <attribute name="number" value="1203"/>
                    </document>
                    <document>
                        <attribute name="Position" value="4"/>
                        <attribute name="qty" value="1"/>
                        <attribute name="number" value="1202"/>
                    </document>
                 </data>
            </document>
        </transaction>
    </transactions>
</xml>

Is this somehow possible with LINQ? I tried to solve it with LINQ, but it is not working


Solution

  • Yes.

    var xDoc = XDocument.Load("path");
    var documents = xDoc.Descendants("document").Where(x => (string)x.Attribute("name") != "Page1")
                  .OrderBy(x => (int)(x.Elements("attribute").First().Attribute("value")))
                  .ToList();
    
    var data = xDoc.Descendants("data").First();
    data.Remove();
    var document = xDoc.Descendants("document").First(x => (string)x.Attribute("name") == "Page1");
    document.Add(new XElement("data", documents));
    xDoc.Save("path");