MSDN - System.out. Kelas Ekstensi Xml.XPath mengatakan:
Ada beberapa penalti kinerja untuk menggunakan metode ini. Menggunakan kueri LINQ ke XML menghasilkan kinerja yang lebih baik.
Dan XPathSelectElement adalah metode ekstensi
Saya telah mengikuti XML. Saya perlu mencari tahu pesan-pesannya dan menggabungkannya. Tantangannya adalah - saya hanya perlu memilih pesan yang berada di bawah Status/StatusMsg/StatusDetail
. Dengan Descendants
, saya menerima semua pesan - bahkan di luar elemen yang diperlukan.
Ini dapat dicapai dengan benar menggunakan XPathSelectElement
. Namun karena XPathSelectElement adalah metode ekstensi, kinerjanya mengalami peningkatan seperti yang ditunjukkan di LINQ ke XML dengan tinjauan kinerja XPath yang menyatakan:
Dalam kebanyakan kasus, menjalankan kueri XPath akan menghasilkan periode eksekusi 5 kali lebih lama dibandingkan kueri menggunakan LINQ standar ke XML.
Apa cara terbaik untuk melakukannya tanpa menggunakan metode ekstensi di LINQ ke XML menggunakan C#?
Catatan: Apakah ada cara untuk mengubah Descendants
untuk tujuan ini?
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>
");
KODE
// 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);
PEMBARUAN
XPath tampaknya lebih cepat daripada menggunakan Descendants dua kali. Tahu kenapa?
// 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());