我有一個字符串,它包含格式正確的xml。我想瀏覽該字符串中的XML以提取某些節點中的文本。如何使用內置的.NET類高效地完成此操作。你會使用哪個.NET XML類,爲什麼?從包含格式良好的用於導航的XML字符串構造XML文檔的有效方法?
非常感謝您的幫助。
注1:Linq對我無效。注2:編輯XML並不重要。只讀訪問是我需要的。
我有一個字符串,它包含格式正確的xml。我想瀏覽該字符串中的XML以提取某些節點中的文本。如何使用內置的.NET類高效地完成此操作。你會使用哪個.NET XML類,爲什麼?從包含格式良好的用於導航的XML字符串構造XML文檔的有效方法?
非常感謝您的幫助。
注1:Linq對我無效。注2:編輯XML並不重要。只讀訪問是我需要的。
對於速度,使用XmlReader
:
using (StringReader sr = new StringReader(myString))
using (XmlReader xr = XmlReader.Create(sr))
{
while (xr.Read())
{
if (xr.NodeType == XmlNodeType.Element && xr.Name == "foo")
{
Console.WriteLine(xr.ReadString());
}
}
}
上面打印出每一個XML文檔中名爲「foo」元素的文本內容。 (嗯,有點ReadString
不處理嵌套的元素非常優雅。)
使用的XPathDocument
較慢,因爲整個文檔被解析,然後才能開始搜索,但它具有簡單的優點:
using (StringReader sr = new StringReader(myString))
{
XPathDocument d = new XPathDocument(sr);
foreach (XPathNavigator n in d.CreateNavigator().Select("//foo/text()"))
{
Console.WriteLine(n.Value);
}
}
如果你不表現或內存利用率而言,這是最簡單的使用XmlDocument
:
XmlDocument d = new XmlDocument();
d.LoadXml(myString);
foreach (XmlNode n in d.SelectNodes("//foo/text()"))
{
Console.WriteLine(n.Value);
}
我會使用XmlDocument.Load()從字符串中獲取DOM。然後可以根據需要使用適當的DOM方法或XPATH來遍歷它。
這取決於XML的結構。如果它比較簡單,那麼最有效的方法是將字符串包裝到StringReader
中,然後將其包裝到XmlReader
中。好處是您不必在內存中創建XML樹,從字符串複製數據 - 您只需逐個讀取節點。
如果文檔結構足夠複雜,您可能需要(或想要)DOM - 在這種情況下XDocument.Parse
應該做的伎倆。
你聽起來像一個好主意,但我沒有訪問到LINQ。 – Newbie 2009-09-28 21:21:05
我沒有看到將它包裝在StringReader中的要點。據我所知,StringReader的唯一目的是有可變的字符串,以便在執行大量的字符串操作時。爲每個字符串操作創建新字符串的開銷隨着StringReader而消失。我沒有看到這怎麼適合這裏? – Henri 2009-09-28 21:23:25
@亨利:你把'StringWriter'和'StringReader'混淆了。 'StringReader'用於在純字符串的頂部提供'TextReader'接口,因爲'XmlReader.Create'需要'TextReader'。 – 2009-09-28 21:24:55
對於導航?大概XPathDocument
:
string s = @"<xml/>";
XPathDocument doc = new XPathDocument(new StringReader(s));
從MSDN,
使用XPath數據模型提供一個快速,只讀,內存中的XML文檔的表示。
與XmlDocument
等不同,它針對只讀使用進行了優化;效率更高但功能更弱(即無法編輯它)。有關如何查詢的說明,請參閱see here。
應該指出的是'XPathDocument'實際上在某些類型的XPath查詢中顯着加快了速度;特別是涉及「前置」或「前同胞」軸的任何事情。 – 2009-09-28 21:39:12
請注意,在本例中創建的StringReader上沒有調用Dispose()。見羅伯特羅斯尼的接受答案。 – ALEXintlsos 2014-10-03 20:14:24
@ALEXintlsos不會誤解我的意思:通常我對'IDisposable'特別迂腐;但是:'StringReader'只是其中*真的,真的*並不重要的情況之一。處置它更正確嗎?當然。它*永遠*重要,以*任何方式? Nope; p – 2014-10-03 20:44:27
代碼示例很好的答案。另外,'XPathNodeIterator'實現'IEnumerable',所以不需要使用'while' - 'foreach'也可以做到這一點,並且更易於閱讀。 – 2009-09-28 22:12:35
你是對的;我編輯了這個例子來證明這一點。 – 2009-09-29 00:00:34