【问题标题】:Sort XML document alphabetically in C#在 C# 中按字母顺序对 XML 文档进行排序
【发布时间】:2022-01-06 02:37:09
【问题描述】:

在 C# 中,按字母顺序对 XML 文档进行排序的最佳方法是什么——元素和属性?例如,如果我以 b.xml 开头,它应该以 a.xml 开头:

目前,我正在考虑递归遍历所有元素,对于每个元素,我将删除其子元素,然后按字母顺序再次添加它们,并对属性执行相同操作。

这是我应该采取的方法还是有更好的方法或现成的功能?

【问题讨论】:

  • 你想做什么?顺序可能很重要,具体取决于 XSD 所说的内容。更改顺序可能会更改文档的含义。如果您想按特定顺序读取元素,您可以申请OrderBy,尤其是在您使用 XDocument 和 LINQ-to-XML 时。如果您还想以新顺序编写元素,则必须创建一个新文档并递归添加有序节点
  • 为什么要这样做? XML 是结构化数据,其中元素的顺序可能很重要(您能想象一个按字母顺序排列的 HTML 文档吗?)。
  • perhaps a ready-made function? 否,因为这是一个非常专业的功能,实际上可能会改变文档的含义。虽然差异化可能有意义,但它会导致真实文档出现问题。想象一下工作流程中的步骤,或空中旅行中的腿。虽然使用 LINQ 并不难——你已经可以使用迭代器遍历树,OrderBy 提供排序
  • 如果您想区分两个 XML 文档,您可以使用 关心顺序的集合操作。另一方面,如果您想对 XML 数据进行排序以便可以使用合并工具,那么排序是有意义的。但是,许多 diff 工具可以忽略 XML 元素的顺序。另一方面,您可以加载两个 XDocument 并使用迭代器对它们进行比较。如果您能想出一种方法来使用密钥识别令牌,您可以将 XDocument 展平为令牌并使用集合操作比较两个令牌流
  • 正如问题所述,我正在尝试按字母顺序对 XML 文档进行排序。除了按字母顺序排序之外,我不想做任何事情。这正是我想要的,这正是我的问题所陈述的。

标签: c# xml


【解决方案1】:

我的回答和你的差不多,不需要删除

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication5
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);
            XElement sortedXml = Sort_XML.sort(doc.Root);
        }
    }
    public class Sort_XML
    {
        static public XElement sort(XElement root)
        {
            XElement sortedRoot = new XElement(root.Name.LocalName);
            sortRecursive(root, sortedRoot);
            return sortedRoot;
        }
        public static void sortRecursive(XElement parent, XElement sortedRoot)
        {
            foreach (XElement child in parent.Elements().OrderBy(x => x.Name.LocalName))
            {
                XElement childElement = new XElement(child.Name.LocalName);
                sortedRoot.Add(childElement);
                foreach(XAttribute attribute in child.Attributes().OrderBy(x => x.Name.LocalName))
                {
                    childElement.Add(new XAttribute(attribute.Name.LocalName, attribute.Value));
                }
                if (child.HasElements) sortRecursive(child, childElement);
            }
        }
    }
}

【讨论】:

    【解决方案2】:

    好的,经过一些试验,我想出了一个适用于我的测试文件的函数。

    private static void SortXml(XmlElement node)
    {
        // Load the child elements into a collection.
        List<XmlElement> childElements = new();
            
        foreach (XmlElement childNode in node.ChildNodes)
        {
            childElements.Add(childNode);
    
            // Call recursively if the child is not a leaf.
            if (childNode.HasChildNodes)
            {
                SortXml(childNode);
            }
        }
    
        // Load the attributes into a collection.
        List<XmlAttribute> attributes = new();
    
        foreach (XmlAttribute attrib in node.Attributes)
        {
            attributes.Add(attrib);
        }
    
        node.RemoveAll();
    
        // Re-add the child elements (sorted).
        foreach (var childNode in childElements.OrderBy(element => element.Name))
        {
            node.AppendChild(childNode);
        }
    
        // Re-add the attributes (sorted).
        foreach (var childNode in attributes.OrderBy(attrib => attrib.Name))
        {
            node.Attributes.Append(childNode);
        }
    }
    

    我稍后会更彻底地测试它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-14
      • 2016-02-08
      • 2015-12-08
      • 1970-01-01
      • 2018-11-20
      • 2013-05-02
      • 2014-02-08
      相关资源
      最近更新 更多