XmlReader.Read()与XmlReader.ReadStartElement()

时间:2017-02-08 10:11:55

标签: c# xml xml-parsing

试图理解&#34;不一致&#34;在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的问题问了这个问题,根据msdnReadStartElement() 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"/> 

1 个答案:

答案 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将读取当前的起始元素。