在 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")
)
它检索 <second>
元素及其所有子元素 (Descendants("second")
)
它遍历 <second>
节点 (foreach var second
)
它根据<code>
节点的code
属性对<component>
(Elements
) 节点进行排序
它将原来的 <second>
节点的子节点替换为新排序的 <component>
节点 (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 进行排序的主要内容,如果未能解决你的问题,请参考以下文章
C#写程序,统计所给字符串中字母的个数、数字的个数和大写字母的个数