在 C# 中使用字母和数字 (code="BC1") 属性对 XML 进行排序

Posted

技术标签:

【中文标题】在 C# 中使用字母和数字 (code="BC1") 属性对 XML 进行排序【英文标题】:Sorting XML with Alphabetic and numeric (code="BC1")Attribute in C# 【发布时间】:2021-09-25 03:58:06 【问题描述】:

我尝试过使用 Linq to xml,它似乎无法正常工作。简而言之,我想根据代码标签中的代码属性进行排序,我想要 xml 作为所需的 我已经尝试过如下操作,但它不起作用请帮帮我。

C#: Sort xml node using attribute value

尝试的代码: 我已经尝试过这段代码,但不确定它是否正确。

var orderedTabs = document.Root
    .Element("component")
    .Elements("intial")
    .Elements("second")
    .Elements("component")
    .Elements("observation")
    .OrderBy(xtab => (string)xtab.Element("code").Attribute("code").Value) 
    .ToList();

XML:

<component>
   <intial>
        <second>
            <component>
                <observation>
                    <templateId root="01"/>
                    <id root="01" />
                    <code code="BC3" />
                    <statusCode code="completed" />
                </observation>
            </component>
            <component>
                <observation>
                    <templateId root="01" />
                    <id root="01" />
                    <code code="BC1" />
                    <statusCode code="completed" />
                </observation>
            </component>
            <component>
                <observation>
                    <templateId root="01" />
                    <id root="01" />
                    <code code="BC2" />
                    <statusCode code="completed" />
                </observation>
            </component>
        </second>
    </intial>
    <intial>
        <second>
            <component>
                <observation>
                    <templateId root="01"/>
                    <id root="01" />
                    <code code="BC6" />
                    <statusCode code="completed" />
                </observation>
            </component>
            <component>
                <observation>
                    <templateId root="01" />
                    <id root="01" />
                    <code code="BC4" />
                    <statusCode code="completed" />
                </observation>
            </component>
            <component>
                <observation>
                    <templateId root="01" />
                    <id root="01" />
                    <code code="BC5" />
                    <statusCode code="completed" />
                </observation>
            </component>
        </second>
    </intial>
</component>

期望的输出:

<component>
   <intial>
        <second>
            <component>
                <observation>
                    <templateId root="01"/>
                    <id root="01" />
                    <code code="BC1" />
                    <statusCode code="completed" />
                </observation>
            </component>
            <component>
                <observation>
                    <templateId root="01" />
                    <id root="01" />
                    <code code="BC2" />
                    <statusCode code="completed" />
                </observation>
            </component>
            <component>
                <observation>
                    <templateId root="01" />
                    <id root="01" />
                    <code code="BC3" />
                    <statusCode code="completed" />
                </observation>
            </component>
        </second>
    </intial>
    <intial>
        <second>
            <component>
                <observation>
                    <templateId root="01"/>
                    <id root="01" />
                    <code code="BC4" />
                    <statusCode code="completed" />
                </observation>
            </component>
            <component>
                <observation>
                    <templateId root="01" />
                    <id root="01" />
                    <code code="BC5" />
                    <statusCode code="completed" />
                </observation>
            </component>
            <component>
                <observation>
                    <templateId root="01" />
                    <id root="01" />
                    <code code="BC6" />
                    <statusCode code="completed" />
                </observation>
            </component>
        </second>
    </intial>
</component>

【问题讨论】:

欢迎来到 ***。请与我们分享到目前为止您尝试了哪些方法以及您遇到的问题。 感谢您回复@PeterCsala 我已经尝试过了,但我不知道我是否以正确的方式进行操作,如果这是错误的,我是否知道正确的方式,以便我可以对 XML 进行排序 code var orderedTabs = document.Root.Element("component").Elements("intial").Elements("second").Elements("component").Elements("observation") .OrderBy(xtab => (string)xtab .Element("code").Attribute("code").Value) .ToList(); 请修改/编辑您的帖子以包含代码 我很困惑,这是我在 *** 上发布的第一个问题,我可以知道你到底指的是什么 每个帖子下都有一个Edit 链接。您可以点击它来更改您的问题以包含更多详细信息。 【参考方案1】:

您只是获取元素并对其执行排序。这只会给出排序后的输出,但不会更改 xml 文档。您必须先排序,然后将未排序的元素替换为已排序的元素。

鉴于您的结构,您可以这样做 -

var items = document.Element("component")
            .Elements("intial")
            .Elements("second");
foreach (var item in items)

    var tabs = item.Elements("component").Elements("observation");
    var orderedTabs = tabs
        .OrderBy(xtab => xtab.Element("code").Attribute("code").Value)
        .Select(s => new XElement("component", s))
        .ToList();
    item.ReplaceAll(orderedTabs);

【讨论】:

【参考方案2】:

我的解决方案:

var unorderedDocument = XDocument.Load("sample.xml");

var seconds = unorderedDocument.Descendants("second");
foreach (var second in seconds)

    var orderedComponents = second.Elements().OrderBy(t => t.Descendants("code").First().Attribute("code").ToString());
    second.ReplaceAll(orderedComponents.ToList());


using var memory = new MemoryStream();
unorderedDocument.Save(memory);
string orderedXml = Encoding.UTF8.GetString(memory.ToArray());
Console.WriteLine(orderedXml.ToString());

它是如何工作的?

它从文件中解析 xml (Descendants("second")) 它检索 &lt;second&gt; 元素及其所有子元素 (Descendants("second")) 它遍历 &lt;second&gt; 节点 (foreach var second) 它根据&lt;code&gt; 节点的code 属性对&lt;component&gt; (Elements) 节点进行排序 它将原来的 &lt;second&gt; 节点的子节点替换为新排序的 &lt;component&gt; 节点 (ReplaceAll) 它将整个文档写入 MemoryStream (Save) 它将 MemoryStream 转换为字符串 (Encoding.UTF8.GetString) 它将结果打印到输出中
<?xml version="1.0" encoding="utf-8"?>
<component>
  <intial>
    <second>
      <component>
        <observation>
          <templateId root="01" />
          <id root="01" />
          <code code="BC1" />
          <statusCode code="completed" />
        </observation>
      </component>
      <component>
        <observation>
          <templateId root="01" />
          <id root="01" />
          <code code="BC2" />
          <statusCode code="completed" />
        </observation>
      </component>
      <component>
        <observation>
          <templateId root="01" />
          <id root="01" />
          <code code="BC3" />
          <statusCode code="completed" />
        </observation>
      </component>
    </second>
  </intial>
  <intial>
    <second>
      <component>
        <observation>
          <templateId root="01" />
          <id root="01" />
          <code code="BC4" />
          <statusCode code="completed" />
        </observation>
      </component>
      <component>
        <observation>
          <templateId root="01" />
          <id root="01" />
          <code code="BC5" />
          <statusCode code="completed" />
        </observation>
      </component>
      <component>
        <observation>
          <templateId root="01" />
          <id root="01" />
          <code code="BC6" />
          <statusCode code="completed" />
        </observation>
      </component>
    </second>
  </intial>
</component>

【讨论】:

以上是关于在 C# 中使用字母和数字 (code="BC1") 属性对 XML 进行排序的主要内容,如果未能解决你的问题,请参考以下文章

浅谈无字母数字构造webshell

C#写程序,统计所给字符串中字母的个数、数字的个数和大写字母的个数

C#正则表达式判断是不是是数字,是不是含有中文,是不是是数字字母组合

getshell不用英文数字

C# 数字和字母

JS 怎么制作数字、字母、汉字混合的验证码