gpt4 book ai didi

c# - 不使用扩展方法选择 XML 元素

转载 作者:数据小太阳 更新时间:2023-10-29 02:31:04 25 4
gpt4 key购买 nike

MSDN - System.Xml.XPath Extensions Class说:

There is some performance penalty for using these methods. Using LINQ to XML queries yields better performance.

XPathSelectElement是一种扩展方法

我有以下 XML。我需要找出消息并将其连接起来。挑战在于 - 我只需要选择 Status/StatusMsg/StatusDetail 下的消息。使用 Descendants,我收到了所有消息 - 甚至在所需元素之外。

这可以使用 XPathSelectElement 正确实现。但由于 XPathSelectElement 是一种扩展方法,它会影响性能,如 LINQ to XML with XPath performance review 所示。其中说:

In most cases running an XPath query will result in a 5 times longer execution period than querying using standard LINQ to XML.

在使用 C# 的 LINQ to XML 中不使用扩展方法的最佳方法是什么?

注意:有没有办法为此调整Descendants

XML

XDocument xDoc = XDocument.Parse(@"  
<Status>
<StatusMsg>
<StatusType>INVOICE</StatusType>

<StatusDetail>
<Sequence test=""K""> 2 </Sequence>
<Message>A</Message>
</StatusDetail>

<StatusDetail>
<Message>B</Message>
</StatusDetail>

<StatusDetail>
<Message>C</Message>
</StatusDetail>
</StatusMsg>

<StatusDetail>
<Message>OUTSIDE</Message>
</StatusDetail>
</Status>
");

代码

// Descendants
var messageArrayWithOutside = xDoc.Descendants(@"StatusDetail")
.Select(
x => x.Element("Message") == null ? String.Empty : x.Element("Message").Value.Trim()
).ToArray();

var textAll = string.Join(", ", messageArrayWithOutside);

//XPathSelectElements
var messageArray = xDoc.XPathSelectElements(@"Status/StatusMsg/StatusDetail")
.Select(
x => x.Element("Message") == null ? String.Empty : x.Element("Message").Value.Trim()
).ToArray();

var text = string.Join(", ", messageArray);

更新

XPath 似乎比使用 Descendants 两次更快。知道为什么吗?

        // Descendants
Stopwatch stopWatchDescendants = new Stopwatch();
stopWatchDescendants.Start();
var messageArrayDecendants = xDoc.Descendants("StatusMsg")
.Descendants("StatusDetail")
.Select(
x => x.Element("Message") == null ?string.Empty : x.Element("Message").Value.Trim()
).ToArray();

var textDecendants = string.Join(", ", messageArrayDecendants);
stopWatchDescendants.Stop();
TimeSpan tsDescendants = stopWatchDescendants.Elapsed;


//XPathSelectElements
Stopwatch stopWatchXPath = new Stopwatch();
stopWatchXPath.Start();
var messageArrayXPath = xDoc.XPathSelectElements(@"Status/StatusMsg/StatusDetail")
.Select(
x => x.Element("Message") == null ? String.Empty : x.Element("Message").Value.Trim()
).ToArray();

var textXPath = string.Join(", ", messageArrayXPath);
stopWatchXPath.Stop();
TimeSpan tsXPath = stopWatchXPath.Elapsed;


if (tsXPath > tsDescendants)
{
Console.WriteLine("LINQ is fast");
}
if (tsDescendants > tsXPath)
{
Console.WriteLine("XPath is fast");
}

Console.WriteLine("XPath :" + tsXPath.ToString());
Console.WriteLine("LINQ :" + tsDescendants.ToString());

最佳答案

您需要使用 .Elements(XName)而不是 .Descendants(XName)像下面这样:

var messageArrayWithOutside = xDoc.Elements("StatusMsg")
.Elements("StatusDetail")
.Select(
x =>
x.Element("Message") == null ?
string.Empty :
x.Element("Message").Value.Trim()
).ToArray();

var textAll = string.Join(", ", messageArrayWithOutside);

然后 textAll 字符串将包含所需的输出并省略 OUTSIDE:

A, B, C

key 似乎在使用 .Elements(XName)这限制了 xDocument 必须对元素的直接子元素进行的搜索。

关于c# - 不使用扩展方法选择 XML 元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15539428/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com