[英]How can I add ISortedEnumerable<XElement> to XElement?
我正在嘗試使用Linq對XElement的子項進行排序,然后將現有的子項替換為sorted。
首先,我創建XElement:
XElement WithLinq =
new XElement("Names",
from cust in Customers.AsEnumerable()
select
new XElement("Customer",
new XAttribute("ID", cust.ID),
new XElement("Name", cust.Name),
new XElement("Purchases",
from pur in cust.Purchases
select
new XElement("Purchase",
new XElement("Produkt",pur.Description),
new XAttribute("ID",pur.ID),
new XElement("Price",pur.Price),
new XComment("teraz daty"),
new XElement("Date",pur.Date), //Formatuje DateTime zgodnie z normami XMLa
new XElement("DataAleNieDoKonca",pur.Date.ToString(CultureInfo.InvariantCulture)))))
);
然后,我對節點進行排序:
var NowaKolejnosc = WithLinq.Elements().Last().Elements().OrderBy(n => n.Name).ThenBy(n => n.Value);
並替換它們:
WithLinq.Elements().Last().ReplaceNodes(NowaKolejnosc);
但是我得到了一個運行時異常:ArgumentException:“無法實現IComparable元素。” 轉換:至少一個對象必須實現IComparable。
我不知道是什么導致異常以及如何解決它。
由於XElement.Name
的類型為System.Xml.Linq.XName,因此發生錯誤。 XName
不實現IComparable
。
XName包裝一個System.String
值,並覆蓋ToString
以返回該System.String
值。
由於System.String
實現了IComparable
我們可以利用此知識來正確,成功地調用OrderBy
。 這具有所需的語義,因為在邏輯上,我們要比較包裝的字符串。
WithLinq.Elements().Last().Elements().OrderBy(n => n.Name.ToString()).ThenBy(n => n.Value)
當使用多個排序LINQ運算符時,我發現使用查詢表達式語法更具可讀性。
from element in WithLinq.Elements().Last().Elements()
orderby element.Name.ToString(), element.Value
select element
這是基於Aluan Haddad接受的答案的評論。
建議:考慮使用XName.LocalName
代替XName.ToString()
:
如果XML不使用名稱空間或特定操作不需要XML中的名稱空間,則直接使用element.Name.LocalName
屬性可能是合適的。
當處理大型(> 1GB)XML文件時,通過將XName.ToString()
換為XName.LocalName
,我發現性能有所提高。
有趣的是,在一個長達1小時的程序中,此更改節省了大約六分鍾的時間,需要重復進行排序和比較。 在其他情況下,YMMV。
在某些情況下,以下是通過參考來源的區別:
/// <summary>
/// Returns the expanded XML name in the format: {namespaceName}localName.
/// </summary>
public override string ToString() {
if (ns.NamespaceName.Length == 0) return localName;
return "{" + ns.NamespaceName + "}" + localName;
}
/// <summary>
/// Gets the local (unqualified) part of the name.
/// </summary>
/// <seealso cref="XName.Namespace"/>
public string LocalName {
get { return localName; }
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.