MSDN - System.Xml.XPath Extensions Class говорит:Выберите XML элемент без использования метода расширения
Существует некоторая производительность штраф за использование этих методов. Использование запросов LINQ to XML обеспечивает лучшую производительность.
И XPathSelectElement является метод расширения
я следующий XML. Мне нужно узнать сообщения и объединить их. Проблема в том, что мне нужно выбрать только сообщения, которые попадают под Status/StatusMsg/StatusDetail
. С Descendants
, я получаю все сообщения - даже вне необходимых элементов.
Этого можно достичь с помощью XPathSelectElement
. Но поскольку XPathSelectElement является метод расширения, он имеет некоторое падение производительности, как показано на LINQ to XML with XPath performance review, который говорит:
В большинстве случаев, где выполняется запрос XPath приведет в 5 раз больше периода выполнения, чем запрос с использованием стандартного LINQ к XML.
Каков наилучший способ сделать это без использования метода расширения в LINQ to XML с использованием C#?
Примечание: существует ли способ для настройки 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);
UPDATE
XPath, кажется, быстрее, чем при использовании потомках два раза. Любая идея почему?
// 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());
Tangent, но ваш вопрос имеет мало общего с методами расширения и многое, что связано с xpath. – JerKimball