试图理解"不一致"在XmlReader.Read()
和XmlReader.ReadStartElement()
之间。在下面的reader1
中,一切都是预期的,即需要3次读取才能读取整个xml;更重要的是,当第一次阅读时,即阅读<firstname>
,reader1.Value
为空。第二次读数reader1.Value
是文本节点值。
但在reader2
中,我期待相同的阅读顺序,因为据我所知ReadStartElement()
内部调用Read()
,它应该只读取一个XmlNodeType
,例如这里是<firstname>
。这几乎就像我们可以通过调用替换ReadStartElement("firstname")
来检查它是否是名为firstname
的起始元素以及对Read()
的调用。为什么在reader2.Value
之后ReadStartElement("firstname")
没有空?
我最初根据@lesscode的问题问了这个问题,根据msdn,ReadStartElement()
XmlReader
会将reader.Value
提升到下一个节点,而Read()
的值是ReadStartElement()
。当前节点。但如果是这样,Read()
和ReadStartElement()
之间不一致,因为使用Value
后必须检索值,而使用 var simpleElement = "<firstname>Jim</firstname>";
using (var reader1 = XmlReader.Create(new StringReader(simpleElement)))
{
var i = 1;
while (reader1.Read())
{
WriteLine($"i = {i++}; value = {reader1.Value}");
}
}
using (var reader2 = XmlReader.Create(new StringReader(simpleElement)))
{
// this internally calls Read() which should have ONLY read the 'firstname' start element node.
reader2.ReadStartElement("firstname");
// prints Jim; but why??? The text node has NOT been read yet!
WriteLine(reader2.Value);
reader2.Read(); //WHY needs this line given text node has been read already?
reader2.ReadEndElement();
}
则必须检索{ {1}}事先。
<?xml version="1.0" encoding="utf-8"?>
<bitmap
xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_back"
android:tint="@color/red_tint"/>
答案 0 :(得分:1)
您可以查看Github上的源代码:XmlReader.cs。
如下所示,这些方法具有不同的行为:
// Checks that the current node is an element and advances the reader to the next node.
public virtual void ReadStartElement() {
if (MoveToContent() != XmlNodeType.Element) {
throw new XmlException(Res.Xml_InvalidNodeType, this.NodeType.ToString(), this as IXmlLineInfo);
}
Read();
}
// Checks whether the current node is a content (non-whitespace text, CDATA, Element, EndElement, EntityReference
// or EndEntity) node. If the node is not a content node, then the method skips ahead to the next content node or
// end of file. Skips over nodes of type ProcessingInstruction, DocumentType, Comment, Whitespace and SignificantWhitespace.
public virtual XmlNodeType MoveToContent() {
do {
switch (this.NodeType) {
case XmlNodeType.Attribute:
MoveToElement();
goto case XmlNodeType.Element;
case XmlNodeType.Element:
case XmlNodeType.EndElement:
case XmlNodeType.CDATA:
case XmlNodeType.Text:
case XmlNodeType.EntityReference:
case XmlNodeType.EndEntity:
return this.NodeType;
}
} while (Read());
return this.NodeType;
}
因此ReadStartElement
方法调用MoveToContent
可以进行多次Read
次调用以查找内容节点。在此之后,ReadStartElement
将读取当前的起始元素。