XmlReader預設是讀取XML檔案中的Whitespace和注釋的。
比如這個XML:
<root>
<!-- root中 -->
<file>
<file.attr>hidden</file.attr>
a.txt
</file>
</root>
XmlReader讀取代碼:
//data.xml代表上面的XML檔案
using (var xr = XmlReader.Create("data.xml"))
{
while (xr.Read())
Console.WriteLine("NodeType:{0,-20} Name:{1}", xr.NodeType, xr.Name);
}
將會輸出:
NodeType:XmlDeclaration Name:xml
NodeType:Whitespace Name:
NodeType:Element Name:root
NodeType:Whitespace Name:
NodeType:Comment Name:
NodeType:Whitespace Name:
NodeType:Element Name:file
NodeType:Whitespace Name:
NodeType:Element Name:file.attr
NodeType:Text Name:
NodeType:EndElement Name:file.attr
NodeType:Text Name:
NodeType:EndElement Name:file
NodeType:Whitespace Name:
NodeType:EndElement Name:root
可以看到,Whitespace和注釋都被讀了進來。
解決方案之一就是在XmlReaderSettings中將IgnoreWhitespace和IgnoreComments設定為True(預設當然是False),然後再建立XmlReader:
var xrs = new XmlReaderSettings();
xrs.IgnoreComments = true;
xrs.IgnoreWhitespace = true;
using (var xr = XmlReader.Create("data.xml", xrs))
{ }
還可以使用XmlReader的MoveToContent方法,可以參考MSDN的全面解釋(http://msdn.microsoft.com/zh-cn/library/system.xml.xmlreader.movetocontent.aspx):
檢查當前節點是否是內容(非空白文本、CDATA、Element、EndElement、EntityReference 或 EndEntity)節點。 如果此節點不是內容節點,則讀取器向前跳至下一個內容節點或檔案結尾。 它跳過以下類型的節點:ProcessingInstruction、DocumentType、Comment、Whitespace 或 SignificantWhitespace。
代碼:
//data.xml代表上面的XML檔案
using (var xr = XmlReader.Create("data.xml"))
{
while (xr.Read())
{
xr.MoveToContent();
Console.WriteLine("NodeType:{0,-20} Name:{1}", xr.NodeType, xr.Name);
}
}
輸出:
NodeType:Element Name:root
NodeType:Element Name:file
NodeType:Element Name:file.attr
NodeType:Text Name:
NodeType:EndElement Name:file.attr
NodeType:Text Name:
NodeType:EndElement Name:file
NodeType:EndElement Name:root
Whitespace和注釋都沒了。
注意不要和XmlReader的兩個其他的方法混淆:MoveToAttribute和MoveToElement,這兩個是在XML元素和屬性之間的移動。
另外許多XmlReader的讀取操作內部會調用MoveToContent方法,比如ReadElementString,ReadStartElement,ReadEndElement……
第三個要說的方法是MoveToFollowing方法,這個方法會一直讀下去直到指定名稱的元素被找到。這樣的話我們直接去找需要的節點而直接省略那些Whitespace或者注釋。
代碼:
//data.xml代表上面的XML檔案
using (var xr = XmlReader.Create("data.xml"))
{
//使用ReadToFollowing讀至file.attr元素
xr.ReadToFollowing("file.attr");
Console.WriteLine(xr.ReadElementString());
//讀取元素內的XML文本
Console.WriteLine(xr.ReadString().Trim());
}
輸出:
hidden
a.txt
注意XML元素內的文位元組點的Whitespace是始終保留的。