【问题标题】:C# xml file sorting tags by id, but saving same name orderC# xml文件按id排序标签,但保存同名顺序
【发布时间】:2019-11-13 16:19:27
【问题描述】:

我试图仅在同名标签之间按 id 对 xml 标签进行排序,我想在他们的孩子身上做同样的事情。现在我只能对根的第一级进行排序。任何想法如何以更有效的方式使其变得更有效?

感谢您的建议。

之前的示例:

<AFDatabase>
        <Element1><id>1</id></Element1>
        <Element1><id>10</id></Element1>
        <Element1><id>5</id></Element1>
        <Element1><id>4</id>
    <ElementInside><id>3</id><ElementInside>
    <ElementInside><id>2</id><ElementInside>
    <ElementInside><id>1</id><ElementInside>
    <ElementInside><id>0</id><ElementInside>
    <ElementInside4><id>3</id><ElementInside4>
    <ElementInside4><id>2</id><ElementInside4>
    <ElementInside4><id>1</id><ElementInside4>
    <ElementInside2><id>3</id><ElementInside2>
    <ElementInside2><id>2</id><ElementInside2>
    <ElementInside2><id>1</id><ElementInside2>
    </Element1>            

///之后///

<AFDatabase>
    <Element1><id>1</id></Element1>
    <Element1><id>4</id>

    <ElementInside><id>0</id><ElementInside>
    <ElementInside><id>1</id><ElementInside>
    <ElementInside><id>2</id><ElementInside>
    <ElementInside><id>3</id><ElementInside>
    <ElementInside4><id>1</id><ElementInside4>
    <ElementInside4><id>2</id><ElementInside4>
    <ElementInside4><id>3</id><ElementInside4>
    <ElementInside2><id>1</id><ElementInside2>
    <ElementInside2><id>2</id><ElementInside2>
    <ElementInside2><id>3</id><ElementInside2>

    </Element1>
    <Element1><id>5</id></Element1>
    <Element1><id>10</id></Element1>

</AFDatabase>

代码

 private static XElement xmlSorting(XElement root)
            {

                var xmlStruct = sortRootBYID(root);



                return new XElement(root.Name,
                        root.Attributes(), new XElement("AFDatabase",

                        from child in root.Nodes()
                        where child.NodeType != XmlNodeType.Element
                        select child,

                        from child in xmlStruct.Elements()
                        select child));


            }

            private static XElement sortRootBYID(XElement root)
            {
               var ElementNames =  getElementNames(root);


                var xmlStruct = new XElement("x");
                xmlStruct.RemoveAll();
                foreach (var elementName in ElementNames)
                {

                    var orderedTags = root.Elements("AFDatabase").Elements(elementName)
                                           .OrderBy(xtab => (string)xtab.Element("id"))
                                           .ToArray();

                    foreach (XElement tag in orderedTags)
                        xmlStruct.Add(tag);


                }

                return xmlStruct;


            }

            private static HashSet<string> getElementNames (XElement root)
            {
                HashSet<string> ElementNames = new HashSet<string>();
                foreach (var element in root.Elements().Elements())
                {
                    //Console.WriteLine();


                    if (element.Name != null)
                    {
                        ElementNames.Add(element.Name.ToString());
                    }
                }



                return ElementNames;
            }

【问题讨论】:

  • 听起来像是递归的工作。

标签: c# xml linq sorting


【解决方案1】:

实现此目的的一种方法如下。您需要先对第一级元素进行排序,然后根据元素名称对内部元素进行分组,然后对它们进行排序。

var xDoc = XDocument.Parse(xml);
var elementCollection = xDoc.Root.Elements("Element1")
                          .OrderBy(x=> int.Parse(x.Element("id").Value)).ToList();

foreach(var element in elementCollection.Where(x=>x.Descendants().Any(c=>c.Name.LocalName.StartsWith("ElementInside"))).ToArray())
{
    var innerElements = element.Descendants()
                         .Where(x=>!x.Name.LocalName.Equals("id"))
                         .GroupBy(x=>x.Name.LocalName)
                         .Select(x=>x.ToList().OrderBy(c=>c.Element("id") == null ? "0" : c.Element("id").Value))
                         .SelectMany(x=>x).ToList();
    innerElements.Insert(0,element.Element("id"));
    element.ReplaceAll(innerElements);
}
var result = new XElement("AFDatabase", elementCollection);

Demo Code

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-07
    • 1970-01-01
    • 2011-08-09
    • 2015-09-16
    相关资源
    最近更新 更多