首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将ISortedEnumerable<XElement>添加到XElement中?

如何将ISortedEnumerable<XElement>添加到XElement中?
EN

Stack Overflow用户
提问于 2017-05-08 11:13:11
回答 2查看 103关注 0票数 2

我试图使用Linq对XElement的子级进行排序,然后用排序替换现有的子级。

首先,我创建XElement:

代码语言:javascript
复制
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)))))    
                        );

然后对节点进行排序:

代码语言:javascript
复制
var NowaKolejnosc = WithLinq.Elements().Last().Elements().OrderBy(n => n.Name).ThenBy(n => n.Value);

并替换它们:

代码语言:javascript
复制
WithLinq.Elements().Last().ReplaceNodes(NowaKolejnosc);

但我得到了一个运行时异常: ArgumentException:'Co实现了ć元素IComparable。‘翻译:至少有一个对象必须实现IComparable。

我不明白是什么导致了异常,以及如何解决它。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-05-08 11:23:46

发生此错误是因为XElement.Name的类型为System.Xml.Linq.XNameXName不实现IComparable

XName封装一个System.String值,并重写ToString以返回该System.String值。

由于System.String实现了IComparable,所以我们可以利用这些知识正确和成功地调用OrderBy。这具有所需的语义,因为在逻辑上,我们希望比较包装好的字符串。

代码语言:javascript
复制
WithLinq.Elements().Last().Elements().OrderBy(n => n.Name.ToString()).ThenBy(n => n.Value)

当使用多个排序LINQ运算符时,我发现使用查询表达式语法更易读。

代码语言:javascript
复制
from element in WithLinq.Elements().Last().Elements()
orderby element.Name.ToString(), element.Value
select element
票数 2
EN

Stack Overflow用户

发布于 2017-05-09 21:26:34

这是在阿伦·哈达德接受的回答的基础上发表的评论。

XName.LocalName建议:考虑使用代替 XName.ToString()**:**

直接使用element.Name.LocalName属性可能是合适的,前提是XML不使用名称空间,或者在特定操作中不需要XML中的名称空间。

在处理大型(> 1GB) XML文件时,我发现通过将XName.ToString()替换为XName.LocalName获得了适度的性能提高。

不过,这一变化在长达1小时的程序中节省了大约6分钟,这需要反复的排序和比较。在其他情况下,YMMV。

对于某些上下文,下面是通过参考源实现的区别

代码语言:javascript
复制
/// <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;
}
代码语言:javascript
复制
/// <summary>
/// Gets the local (unqualified) part of the name.
/// </summary>
/// <seealso cref="XName.Namespace"/>
public string LocalName {
    get { return localName; }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43846208

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档