我想用LINQ对XML文件进行排序。 XML在下面,仅是一个示例。通常它更大更复杂。 XML应按标题升序排序。不是整个XML,而是每个parentNode本身。叶子总是在底部。文件夹或非叶子位于顶部。以下XML已经结构良好,但标题的顺序错误。排序算法还应该替换错误定位的非叶节点。 我已经有一些代码可以完成这项工作,但我想知道是否有更优雅或更短的方式。目前我必须调用函数递归来进行转换。也许这可以用另一种方式完成。 谢谢。
雷
这是我的XML:
<Node title="text99" leaf="no">
<Node title="text98" leaf="no">
<Node title="text97" leaf="no">
<Node title="text96" leaf="yes"/>
<Node title="text95" leaf="yes"/>
</Node>
<Node title="text94" leaf="no">
<Node title="text93" leaf="yes"/>
<Node title="text92" leaf="yes"/>
</Node>
<Node title="text91" leaf="yes"/>
<Node title="text90" leaf="yes"/>
</Node>
<Node title="text89" leaf="no">
<Node title="text88" leaf="no">
<Node title="text87" leaf="yes"/>
<Node title="text86" leaf="yes"/>
</Node>
<Node title="text85" leaf="no">
<Node title="text84" leaf="yes"/>
<Node title="text83" leaf="yes"/>
</Node>
<Node title="text82" leaf="yes"/>
<Node title="text81" leaf="yes"/>
</Node>
<Node title="text80" leaf="no">
<Node title="text79" leaf="no">
<Node title="text78" leaf="no">
<Node title="text78" leaf="yes"/>
<Node title="text77" leaf="yes"/>
</Node>
<Node title="text76" leaf="no">
<Node title="text75" leaf="yes"/>
<Node title="text74" leaf="yes"/>
</Node>
<Node title="text73" leaf="yes"/>
<Node title="text72" leaf="yes"/>
</Node>
<Node title="text71" leaf="no">
<Node title="text70" leaf="no">
<Node title="text69" leaf="yes"/>
<Node title="text68" leaf="yes"/>
</Node>
<Node title="text67" leaf="no">
<Node title="text66" leaf="yes"/>
</Node>
<Node title="text65" leaf="yes"/>
<Node title="text64" leaf="yes"/>
</Node>
<Node title="text63" leaf="yes"/>
<Node title="text62" leaf="yes"/>
</Node>
<Node title="text61" leaf="yes"/>
<Node title="text60" leaf="yes"/>
这是我的代码:
using (XmlReader reader = XmlReader.Create(XmlStream))
{
XDocument xDoc = XDocument.Load(reader);
Action<XElement> sortXml = null;
sortXml = xElement =>
{
bool sortParentNode = false;
foreach (var xElem in xElement.Elements())
{
if (xElem.HasElements)
{
// go into deep
sortXml(xElem);
}
else
{
// break loop and sort parentNode
sortParentNode = true;
break;
}
}
if (sortParentNode)
{
xElement.ReplaceNodes(from node in xElement.Elements()
orderby node.Attribute("title").Value
group node by node.HasElements into folderGroup
orderby folderGroup.Key descending
select folderGroup);
}
};
sortXml(xDoc.Root);
}
答案 0 :(得分:7)
XML应按标题排序, 上升。不是整个XML, 但是每个父节点都是自己的。叶子 始终处于最底层。文件夹或 非叶子在顶部。
此解决方案似乎符合您的要求:
public static void SortXml(XElement node)
{
node.ReplaceNodes(node.Elements("Node")
.OrderBy(x => (string)x.Attribute("leaf"))
.ThenBy(x => (string)x.Attribute("title")));
foreach (var childNode in node.Elements("Node"))
SortXml(childNode);
}
...
XDocument doc = XDocument.Load("test.xml");
SortXml(doc.Root);
所有子节点首先按叶属性的值排序(按字母顺序使用“是”之前的“否”),并按标题次要排序。所有第一级子节点都以这种方式排序,然后使用每个子节点作为输入递归重复。
<强>输出:强>
<Node title="text99" leaf="no">
<Node title="text80" leaf="no">
<Node title="text71" leaf="no">
<Node title="text67" leaf="no">
<Node title="text66" leaf="yes" />
</Node>
<Node title="text70" leaf="no">
<Node title="text68" leaf="yes" />
<Node title="text69" leaf="yes" />
</Node>
<Node title="text64" leaf="yes" />
<Node title="text65" leaf="yes" />
</Node>
<Node title="text79" leaf="no">
<Node title="text76" leaf="no">
<Node title="text74" leaf="yes" />
<Node title="text75" leaf="yes" />
</Node>
<Node title="text78" leaf="no">
<Node title="text77" leaf="yes" />
<Node title="text78" leaf="yes" />
</Node>
<Node title="text72" leaf="yes" />
<Node title="text73" leaf="yes" />
</Node>
<Node title="text62" leaf="yes" />
<Node title="text63" leaf="yes" />
</Node>
<Node title="text89" leaf="no">
<Node title="text85" leaf="no">
<Node title="text83" leaf="yes" />
<Node title="text84" leaf="yes" />
</Node>
<Node title="text88" leaf="no">
<Node title="text86" leaf="yes" />
<Node title="text87" leaf="yes" />
</Node>
<Node title="text81" leaf="yes" />
<Node title="text82" leaf="yes" />
</Node>
<Node title="text98" leaf="no">
<Node title="text94" leaf="no">
<Node title="text92" leaf="yes" />
<Node title="text93" leaf="yes" />
</Node>
<Node title="text97" leaf="no">
<Node title="text95" leaf="yes" />
<Node title="text96" leaf="yes" />
</Node>
<Node title="text90" leaf="yes" />
<Node title="text91" leaf="yes" />
</Node>
<Node title="text60" leaf="yes" />
<Node title="text61" leaf="yes" />
</Node>