我想看看这些建议的解决方案中哪个表现最佳,因此我进行了一些比较测试。出于兴趣,我还将LINQ方法与Greg建议的旧的System.Xml方法进行了比较。变化很有趣,不是我所期望的,最慢的方法比最快的方法慢
3倍以上。
按从最快到最慢的顺序列出的结果如下:
- CreateReader - Instance Hunter(0.113秒)
- Plain old System.Xml - Greg Hurlman(0.134秒)
- Aggregate with string concatenation - Mike Powell(0.324秒)
- StringBuilder - Vin(0.333秒)
- String.Join on array - Terry(0.360秒)
- String.Concat on array - Marcin Kosieradzki(0.364秒)
方法
我使用了一个包含20个相同节点(称为“hint”)的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>
上面显示的秒数是提取20个节点的“内部XML”,连续1000次并取5次平均值的结果。我没有包括将XML加载和解析为
XmlDocument
(对于
System.Xml方法)或
XDocument
(对于其他所有方法)所需的时间。
我使用的LINQ算法是:
(C#-所有算法都需要一个XElement
“parent”并返回内部XML字符串)
CreateReader:
var reader = parent.CreateReader();
reader.MoveToContent();
return reader.ReadInnerXml();
使用字符串连接进行聚合:
return parent.Nodes().Aggregate("", (b, node) => b += node.ToString());
StringBuilder:
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方法。
如果您正在使用具有大量节点的大型元素的XML(可能有100个以上的节点),那么您可能会开始看到使用StringBuilder
优于Aggregate方法的好处,但不优于CreateReader
。我认为在这些条件下,Join
和Concat
方法永远不会更有效,因为将一个大型列表转换为大型数组的惩罚很大(即使在较小的列表中也很明显)。
parent.CreateNavigator().InnerXml
这一段代码(需要引用System.Xml.XPath
命名空间来使用扩展方法)。 - Richard.Concat
里需要使用.ToArray()
,但它似乎可以让它更快。 - drzaus.ToString()
中剥离容器/根。看起来甚至更快... - drzausvar reader = parent.CreateReader();
周围加上 using 语句。 - BrainSlugs83