Сортировка XMLDocument с использованием linq - PullRequest
2 голосов
/ 03 августа 2011

Кажется, я не могу понять, как это сделать.Здесь есть несколько других примеров, но ничего не соответствует тому, что я хочу сделать:

Рассмотрим следующий объект XMLDocument:

<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>

Как мне поступить при сортировке этого документа на основеузел "sortOrder", использующий linQ или другой метод?

После сортировки externalxml должен выглядеть примерно так:

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

UPDATE

Iдостигнут определенный прогресс, теперь данные отсортированы, но как мне обновить исходный несортированный XmlDocument?Это то, что у меня есть:

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

Мне нужно применить изменения обратно к «policyDocument».Примечание. Обложка может иметь собственную группу CoverGroup, которая затем может снова иметь обложки с собственными группами CoverGroup.Это понижает по крайней мере 4 уровня: то есть

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

XPATH и foreach выше cathers для вышеупомянутой структуры, поэтому я думал о, возможно, просто замене coverGroup XmlNode в первом foreachс новым отсортированным списком, но я не знаю, как восстановить новый XmlNode.Если мы можем понять это, то мы можем просто сделать это:

policyDocument.ReplaceChild(coverGroup, mySortedXmlNode)

Ответы [ 3 ]

2 голосов
/ 03 августа 2011

Вы можете попробовать следующее (используя XDocument, а не 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));

Я пишу код, не тестируя его, но я думаю, что это хорошая отправная точка.

1 голос
/ 03 августа 2011

Если бы вы начали с XDocument с самого начала, сделать это было бы легко.Это может быть так же просто, как сделать это:

XDocument doc = ...;
var baseElement = doc.XPathSelectElement("/Policy/Covers");
var sortedElements = baseElement.Elements()
    .OrderBy(e => (int)e.XPathSelectElement("properties/sortOrder"))
    .ToList(); // this call may or may not be needed, but just in case...
baseElement.ReplaceAll(sortedElements);

Ваш документ будет в конечном итоге отсортирован, и вы сможете сохранить его в свой XML-файл или еще что-то.

В общем, вы не должнысмешивание обычного DOM XmlDocument с API LINQ XDocument.Выберите один или другой.ИМХО будет гораздо интереснее LINQ to XML.

1 голос
/ 03 августа 2011

Сортировка xml с использованием Linq в Xml.

var doc = XDocument.Parse(xmlString); //the xml string you want to sort
var sortedElements = (from x in doc.Descendants("properties")
                      orderby x.Element("sortOrder").Value
                      select new XElement(x.Parent.Name));

var outputResult = new XElement("Policy", new XElement("Covers", sortedElements));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...