根据属性值对XContainer进行排序

时间:2018-11-22 08:06:57

标签: c# linq-to-xml

任何人都可以帮助我根据属性值对XmlDocument进行排序。

我给出了一个具有几个attr元素的示例xml。因此,我想基于具有属性Name =“ from”的元素的“ value”属性对其进行排序,我正在尝试使用linq to xml来实现这一点。

这是我尝试的一个示例代码。但是它仅保留排序后的“来自”属性。我希望在期望的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 :(得分:0)

您的LINQ语句必须通过childEl.Parent返回父元素(包含from-attribute的元素)。

从您的问题尚不清楚,您的容器是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);