【问题标题】:Sort XMLDocument using linq使用 linq 对 XMLDocument 进行排序
【发布时间】:2011-08-03 05:45:54
【问题描述】:

我似乎无法弄清楚如何做到这一点。这里还有其他几个例子,但没有什么真正符合我想要做的:

考虑以下 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>

我将如何使用 linQ 或其他方法根据节点“sortOrder”对该文档进行排序?

排序后的outerxml基本上应该是这样的:

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

更新

我已经取得了一些进展,数据现在已经排序,但是如何更新原始未排序的 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 用于上述结构,所以我想也许只是用新的排序列表替换第一个 foreach 中的 coverGroup XmlNode,但我不知道如何重建一个新的 XmlNode。如果我们可以解决这个问题,那么我们可以简单地这样做:

policyDocument.ReplaceChild(coverGroup, mySortedXmlNode)

【问题讨论】:

  • 我认为缺少一些东西。请更好地说明您的意思。
  • 请不要使用编辑机制来扩展/更改问题。而是发布一个新的。

标签: c# xml linq sorting


【解决方案1】:

您可以尝试如下(使用 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));

我没有测试就编写代码,但我认为应该是一个很好的起点。

【讨论】:

    【解决方案2】:

    如果您从一开始就使用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 与 LINQ XDocument API 混合使用。选择一个或另一个。恕我直言,LINQ to XML 将是更好的选择。

    【讨论】:

      【解决方案3】:

      使用 Linq to Xml 对 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));
      

      【讨论】:

      • 你觉得我的解决方案有帮助吗@FaNIX?
      猜你喜欢
      • 2015-06-18
      • 2012-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多