Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
287 views
in Technique[技术] by (71.8m points)

c# - Sort XMLDocument using linq

I can't seem to figure out how to do this. There are several other examples on here, but nothing really matches what I want to do:

Consider the following XMLDocument object:

<Policy>
    <Covers>
        <MyCover1>
            <properties>
                <sortOrder>1</sortOrder>
            </properties>
        </MyCover1>

        <MyCover3>
            <properties>
                <sortOrder>3</sortOrder>
            </properties>
        </MyCover3>

        <MyCover2>
            <properties>
                <sortOrder>2</sortOrder>
            </properties>
        </MyCover2>
    </Covers>
</Policy>

How would I go about in sorting this document based on node "sortOrder" using linQ or another method?

After the sort the outerxml should basically look like this:

<Policy>
    <Covers>
        <MyCover1/>
        <MyCover2/>
        <MyCover3/>
    </Covers>
</Policy>

UPDATE

I've made some progress, the data is now sorted, but how do I update the original unsorted XmlDocument? This is what I have so far:

private static void DoSort(XmlDocument policyDocument)
{
    foreach(XmlNode coverGroup in policyDocument.SelectNodes("//CoverGroup"))
    {
        XDocument test = XDocument.Parse(coverGroup.OuterXml);
        var sorted = from xe in test.Element("CoverGroup").Elements()
             let so = xe.Element("properties").Element("displayOrder")
             let num = (int)so
             orderby num
             select xe;     

        var result = new XElement("CoverGroup", sorted);
    }
}

I need to apply the changes back to "policyDocument". Note: A cover can have a CoverGroup of it's own, which can then again have Covers with CoverGroups of it's own. This goes down at least 4 levels: ie

<Policy>
<Covers>
    <MyCover1>
        <properties>
            <sortOrder></sortOrder>
        </properties>
        <CoverGroup>
            <MyCover1Child>
                <properties>
                    <sortOrder></sortOrder>
                </properties>
            </MyCover1Child>
        </CoverGroup>
    </MyCover1>
    ...
</Covers>

The XPATH and foreach above cathers for the above structure, so I was thinking of maybe just replacing the coverGroup XmlNode in the first foreach with the new sorted list, but I dont know how to reconstruct a new XmlNode. IF we can figure this out, then we can simply do this:

policyDocument.ReplaceChild(coverGroup, mySortedXmlNode)
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You may try as follows (using XDocument, not XmlDocument):

var document = XDocument.Parse( /* the xml string */ );

var sorted = from xe in document.Element("Policy").Element("Covers").Elements()
             let so = xe.Element("properties").Element("sortOrder")
             let num = (int)so
             orderby num
             select xe;

var result = new XElement("Policy", new XElement("Covers", sorted));

I write the code without testing it, but I think should be a good starting point.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...