我尝试过使用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>