[英]Sorting XML using LINQ
我想用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);
}
XML應按標題升序排序。 不是整個XML,而是每個parentNode本身。 葉子總是在底部。 文件夾或非葉子位於頂部。
此解決方案似乎符合您的要求:
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>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.