我想看看这些建议的解决方案中哪一个表现最好,所以我进行了一些比较测试。出于兴趣,我还将 LINQ 方法与Greg 建议的普通旧System.Xml方法进行了比较。变化很有趣,不是我所期望的,最慢的方法比最快的方法慢 3 倍以上。
结果按最快到最慢排序:
- CreateReader - 实例猎手(0.113 秒)
- 普通的旧 System.Xml - Greg Hurlman(0.134 秒)
- 使用字符串连接进行聚合 - Mike Powell(0.324 秒)
- StringBuilder - Vin (0.333 秒)
- String.Join on array - Terry (0.360 秒)
- 数组上的 String.Concat - Marcin Kosieradzki (0.364)
方法
我使用了一个包含 20 个相同节点的 XML 文档(称为“提示”):
<hint>
<strong>Thinking of using a fake address?</strong>
<br />
Please don't. If we can't verify your address we might just
have to reject your application.
</hint>
上面显示的秒数是连续提取 1000 次 20 个节点的“内部 XML”并取 5 次运行的平均值(平均值)的结果。我没有包括将 XML 加载和解析为XmlDocument
(对于System.Xml方法)或XDocument
(对于所有其他方法)所花费的时间。
我使用的 LINQ 算法是:(C# - 都采用XElement
“父”并返回内部 XML 字符串)
创建阅读器:
var reader = parent.CreateReader();
reader.MoveToContent();
return reader.ReadInnerXml();
用字符串连接聚合:
return parent.Nodes().Aggregate("", (b, node) => b += node.ToString());
字符串生成器:
StringBuilder sb = new StringBuilder();
foreach(var node in parent.Nodes()) {
sb.Append(node.ToString());
}
return sb.ToString();
String.Join 数组:
return String.Join("", parent.Nodes().Select(x => x.ToString()).ToArray());
数组上的 String.Concat:
return String.Concat(parent.Nodes().Select(x => x.ToString()).ToArray());
我没有在这里展示“Plain old System.Xml”算法,因为它只是在节点上调用 .InnerXml。
结论
如果性能很重要(例如大量 XML,经常解析),我每次都会使用 Daniel 的CreateReader
方法。如果您只是做一些查询,您可能想要使用 Mike 更简洁的 Aggregate 方法。
如果您在具有大量节点(可能有 100 个)的大型元素上使用 XML,您可能会开始看到使用StringBuilder
Aggregate 方法的好处,但不会超过CreateReader
. 我不认为Join
andConcat
方法在这些条件下会更有效,因为将大列表转换为大数组的代价(即使在这里使用较小的列表也很明显)。