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



我尝试过使用Linq对xml进行排序,但似乎不起作用。简而言之,我想要基于代码标记中的Code属性进行排序,我想要所需的xml我试过按下面的方法做,但不起作用。请帮帮我。

C#:使用属性值对xml节点进行排序

尝试的代码:我尝试过这个代码,我不确定它是否正确。

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>

您只需要获取元素并对其进行排序。这只会给出排序后的输出,但不会更改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);
}

我的解决方案:

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());

它是如何工作的

  • 它从文件(Descendants("second")(中解析xml
  • 它检索<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>

最新更新