Сортировка XContainer по значению атрибута - PullRequest
0 голосов
/ 22 ноября 2018

Может ли кто-нибудь помочь мне отсортировать XmlDocument на основе значения атрибута.

Я дал образец xml, содержащий несколько элементов attr.Поэтому я хочу отсортировать его по атрибуту «value» элементов, имеющих атрибут Name = «from». Я пытаюсь добиться этого, используя linq to xml.

Вот один пример кода, который я пробовал.Но он сохраняет только атрибуты from в отсортированном порядке.Я хочу, чтобы все атрибуты, как показано ниже под ожидаемым XML.

container.ReplaceNodes(
            from childEl in container.Elements().Elements()
            where childEl.Attribute("Name")?.Value == "from"
            orderby childEl.Attribute("Value")?.Value descending
            select childEl
        );
        foreach (XElement childEl in container.Elements().Where(e => e.HasElements))
    {
        SortByName(childEl);
    }

Входной XML:

`<Attrs>
  <Attr Name="zddressprevious" isVerified="false">
    <Attr Name="from" Value="2014-01-01" isVerified="false" />
    <Attr Name="house" Value="3" isVerified="false" />
    <Attr Name="street" Value="Test Street" isVerified="false" />
  </Attr>
  <Attr Name="addressprevious" isVerified="false">
    <Attr Name="from" Value="2015-01-01" isVerified="false" />
    <Attr Name="house" Value="1" isVerified="false" />
    <Attr Name="street" Value="Acacia Avenue" isVerified="false" />
  </Attr>
  <Attr Name="addressprevious" isVerified="false">
    <Attr Name="from" Value="2016-01-01" isVerified="false" />
    <Attr Name="house" Value="1" isVerified="false" />
    <Attr Name="street" Value="Test Street" isVerified="false" />
   </Attr>
</Attrs>`

Ожидаемый вывод:

`<?xml version="1.0" encoding="utf-8"?>
<Attrs>
  <Attr <Attr Name="addressprevious" isVerified="false">
    <Attr Name="from" Value="2016-01-01" isVerified="false" />
    <Attr Name="house" Value="1" isVerified="false" />
    <Attr Name="street" Value="Test Street" isVerified="false" />
   </Attr>
   <Attr Name="addressprevious" isVerified="false">
    <Attr Name="from" Value="2015-01-01" isVerified="false" />
    <Attr Name="house" Value="1" isVerified="false" />
    <Attr Name="street" Value="Acacia Avenue" isVerified="false" />
  </Attr>
  <Attr Name="zddressprevious" isVerified="false">
    <Attr Name="from" Value="2014-01-01" isVerified="false" />
    <Attr Name="house" Value="3" isVerified="false" />
    <Attr Name="street" Value="Test Street" isVerified="false" />
  </Attr>
</Attrs>`

1 Ответ

0 голосов
/ 23 ноября 2018

Ваш оператор LINQ должен возвратить родительский элемент (того, который содержит атрибут from) через childEl.Parent.

Из вашего вопроса не совсем ясно, является ли вашконтейнером является XDocument или XElement.

В случае XElement оператор LINQ выглядит следующим образом:

var q =
    from childEl in container.Elements("Attr").Elements("Attr")                
    where childEl.Attribute("Name")?.Value == "from"
    orderby childEl.Attribute("Value")?.Value descending
    select childEl.Parent
    ;

изамените на:

container.ReplaceNodes(q);

Обратите внимание, что оператор LINQ без явного указания имен элементов Attr также сделает работу:

var q =
    from childEl in container.Elements().Elements()                
    where childEl.Attribute("Name")?.Value == "from"
    orderby childEl.Attribute("Value")?.Value descending
    select childEl.Parent
    ;



В случае XDocument ваш запрос должен выглядеть следующим образом:

var q =
    from childEl in container.Element("Attrs").Elements("Attr").Elements("Attr")                
    where childEl.Attribute("Name")?.Value == "from"
    orderby childEl.Attribute("Value")?.Value descending
    select childEl.Parent
    ;

, и вам необходимо заменить узлы с помощью:

container.Element("Attrs").ReplaceAll(q);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...