【问题标题】:How do I sort a List<IGrouping<string, XElement>> in custom order?如何按自定义顺序对 List<IGrouping<string, XElement>> 进行排序?
【发布时间】:2019-02-28 12:52:59
【问题描述】:

我有一个 XML,我想对具有相同值的多个元素进行分组。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE repub SYSTEM "C:\repub\Repub_V1.dtd">
<?xml-stylesheet href="C:\repub\repub.xsl" type="text/xsl"?>
<repub>
<head>
<title>xxx</title>
</head>
<body>
<sec>
<title>First Title</title>
<break name="1-1">
<heading><page num="1"/>First Heading</heading>
<bl>This is another text</bl>
<p>This is a paragraph</p>
</break>
</sec>
<sec>
<title>Second Title</title>
<break name="2-1">
<heading><page num="1"/>Second Heading</heading>
<bl>This is another text</bl>
<p>This is a paragraph</p>
</break>
</sec>
<sec>
<title>First Title</title>
<break name="3-1">
<heading><page num="1"/>Third Heading</heading>
<bl>This is another text</bl>
<p>This is a paragraph</p>
</break>
</sec>
<sec>
<title>Third Title</title>
<break name="4-1">
<heading><page num="1"/>Fourth Heading</heading>
<bl>This is another text</bl>
<p>This is a paragraph</p>
</break>
<break name="5-1">
<heading><page num="1"/>Fifth Heading</heading>
<bl>This is another text</bl>
<p>This is a paragraph</p>
</break>
</sec>
</body>
</repub>

我已经对这些值进行了分组,但它是List&lt;IGrouping&lt;string, XElement&gt;&gt; 格式,这不是问题。

问题是我想检查列表中的值并查看是否存在特定值,例如,在这种情况下,“第三个标题”。因此,无论何时,在任何 XML 中,如果有第三个标题,它将始终位于顶部,即 [0],其余的将在它们出现时出现。

我想知道如何自定义我的列表。

问候 阿曼

【问题讨论】:

    标签: c# .net xml visual-studio linq


    【解决方案1】:

    使用带有 Xml Linq 的字典:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.Xml.Linq;
    
    namespace ConsoleApplication103
    {
        class Program
        {
    
            const string FILENAME = @"c:\temp\test.xml";
            static void Main(string[] args)
            {
                XDocument doc = XDocument.Load(FILENAME);
    
                Dictionary<string, XElement> dic = doc.Descendants("sec")
                   .GroupBy(x => (string)x.Element("title"), y => y)
                   .ToDictionary(x => x.Key, y => y.FirstOrDefault());
    
            }
        }
    
    }
    

    没有字典的移动元素


    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.Xml.Linq;
    
    namespace ConsoleApplication103
    {
        class Program
        {
    
            const string FILENAME = @"c:\temp\test.xml";
            static void Main(string[] args)
            {
                XDocument doc = XDocument.Load(FILENAME);
    
                XElement body = doc.Descendants("body").FirstOrDefault();
    
                List<XElement> results = body.Descendants("sec").Where(x => (string)x.Element("title") == "First Title").ToList();
                if (results != null)
                {
                    List<XElement> breaks = results.SelectMany(x => x.Elements("break")).ToList();
    
                    XElement newElement = XElement.Parse(results.FirstOrDefault().ToString());
                    newElement.Elements("break").Remove();
                    results.Remove();
                    newElement.Add(breaks);
                    body.AddFirst(newElement);
                }
    
            }
        }
    
    }
    

    【讨论】:

    • 您好!是的,它把“第三个标题”带到了顶部,但问题是 List> 有组织的数据。我的意思是,可以有多个“第三个标题”的值,所以我的List>已经对数据进行了排序。例如,如果有3个同名的部分,值为3-1, 9-1, 11-1,那么我将只有一个名为“第三标题”的部分,它将包含所有 后代。这部分我已经完成了,现在我想检查“第三个标题”,如果存在,那么它将位于顶部,其余的将在它们出现时加入。
    • 像魅力一样工作:)
    【解决方案2】:

    不确定您的情况的语法,但这里有一个您应该能够轻松适应的字符串列表的解决方案。

    List<string> strings = new List<string>
    {
        "First title",
        "Second title",
        "Third title",
        "Fourth title",
        "Fifth title"
    };
    
    // Create a mask and convert it to List so we have .IndexOf()
    var mask = new [] { "Third title" }.ToList();
    
    // Bring items that match the mask on top and we don't care about the rest.
    var sorted = strings.OrderByDescending(s => mask.IndexOf(s));
    
    Console.WriteLine($"Sorted:\n{string.Join(",\n", sorted)}");
    
    /*
    Sorted:
    Third title,
    First title,
    Second title,
    Fourth title,
    Fifth title
    */
    

    【讨论】:

      猜你喜欢
      • 2017-09-07
      • 2019-05-28
      • 2017-11-02
      • 2021-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-18
      相关资源
      最近更新 更多