Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 关于XmlReader.ReadSubtree方法的澄清_C#_Xml_Xmlreader - Fatal编程技术网

C# 关于XmlReader.ReadSubtree方法的澄清

C# 关于XmlReader.ReadSubtree方法的澄清,c#,xml,xmlreader,C#,Xml,Xmlreader,我阅读了有关此方法的mdsn文档,但我无法找出以下行为的原因: 假设有以下xml: <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <project> <caseInformation Name="1"> <field >aaaaaaa</field> <field >bvbbbb</field>

我阅读了有关此方法的mdsn文档,但我无法找出以下行为的原因:

假设有以下xml:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<project>
    <caseInformation Name="1">
        <field >aaaaaaa</field>
        <field >bvbbbb</field>
        <field >cccc</field>
        <field >ddddd</field>
    </caseInformation>
</project>
这将产生以下输出:

<field>aaaaaaa</field>

<field>bvbbbb</field>

<field>cccc</field>

<field>ddddd</field>
我得到相同的输出。但我不明白为什么

msdn上声明:

ReadSubTree()返回一个新的XmlReader实例,该实例可用于读取当前节点及其所有子节点

关闭新的XML读取器后,原始读取器将定位在子树的EndElement节点上


这意味着,当我移动innerReader时,原始阅读器也会移动

实际上,ReadSubtree()方法返回的新XmlReader实际上不是新的XmlReader,而是源XmlReader上的包装器

您可以在框架中看到:

xmlsubtrereader
继承自
XmlWrappingReader

如果您看到构造函数:

    internal XmlWrappingReader( XmlReader baseReader ) {
        Debug.Assert( baseReader != null );
        this.reader = baseReader;
        this.readerAsIXmlLineInfo = baseReader as IXmlLineInfo;
    }

这意味着当我移动innerReader时 原版读者移动

确切地说,无论如何,这不是一个问题,因为在“子读取器”关闭之前,您不应该调用原始读取器上的方法,否则您将得到一个异常

基于示例代码的方法使用示例:

    public void ReadProjectInfo()
    {
        //...

        while (reader.Read())
        {
            if (reader.NodeType == XmlNodeType.Element)
            {
                if (reader.Name == "caseInformation")
                {
                    ReadCaseInformation(reader.ReadSubtree());
                }
            }
        }
    }

    public void ReadCaseInformation(XmlReader reader)
    {
        try
        {
            // if something raise an exception here
            // the main reader is not really affected by that
            // because when the methods ends, the "subReader" is closed
            // and then the main reader is set on the closing tag.
            // so the main XML reader can continue to analyze the xml stream
        }
        catch (Exception)
        {
            //...
        }
    }
希望这有助于取代:

var element = (XElement)XNode.ReadFrom(innerReader);
致:

输出:

aaaaaaa
bvbbbb
cccc
ddddd

“当我移动innerReader时,原始读取器也会移动?”,是的,原地不动有什么用?@Henkholtman,如果对后者的操作同时也反映在原始读取器上,那么创建innerReader有什么意义?我的意思是,我知道当innerReader关闭时,原始的一个将被放置在子树的关闭标记处,但是阅读文档时,我会解释这一点,,,当我关闭innerReaderWell时。。。这很棘手,我不确定我是否理解你的问题了。子树提供了一个封闭的作用域,阻止您阅读过多内容。你有什么问题?我真的没有问题。我的意思是,我发现这一点是因为我自己犯了一个错误,使用了第二个实例,所有的东西都起了作用,不管从技术上讲这是不正确的。我本以为会有不同的结果。但由于使用XmlReader一点也不容易,我想知道是什么导致了这种行为,以及这是否会以任何方式影响我未来的工作。不幸的是,文档非常糟糕,没有解释很多我正在做的事情。虽然这在只需要内容的环境中可能有用,但问题的关键是理解XmlReader是如何工作的,特别是ReadSubtree是如何工作的
    public void ReadProjectInfo()
    {
        //...

        while (reader.Read())
        {
            if (reader.NodeType == XmlNodeType.Element)
            {
                if (reader.Name == "caseInformation")
                {
                    ReadCaseInformation(reader.ReadSubtree());
                }
            }
        }
    }

    public void ReadCaseInformation(XmlReader reader)
    {
        try
        {
            // if something raise an exception here
            // the main reader is not really affected by that
            // because when the methods ends, the "subReader" is closed
            // and then the main reader is set on the closing tag.
            // so the main XML reader can continue to analyze the xml stream
        }
        catch (Exception)
        {
            //...
        }
    }
var element = (XElement)XNode.ReadFrom(innerReader);
var element = innerReader.ReadElementContentAsString();
aaaaaaa
bvbbbb
cccc
ddddd