如果没有空格分隔符,为啥 XmlReader 会跳过所有其他元素?

Posted

技术标签:

【中文标题】如果没有空格分隔符,为啥 XmlReader 会跳过所有其他元素?【英文标题】:Why does XmlReader skip every other element if there is no whitespace separator?如果没有空格分隔符,为什么 XmlReader 会跳过所有其他元素? 【发布时间】:2011-01-18 23:15:31 【问题描述】:

当我尝试使用 LINQ XmlReader 类解析 XML 时,我看到了奇怪的行为。下面的测试用例:看起来我是否在 XmlReader 上使用 (XElement)XNode.ReadFrom(xmlReader)Read() 方法之一,它错过了输入 XML 中的第二个 bar 元素。如果在</bar><bar> 之间添加了任何空格,那么它将正确解析第二个bar 元素。

有没有人知道为什么输入流会混乱以及如何解决这个问题?

    [Test]
    [Explicit]
    public void ShouldParseCorrectNumberOfElements()
    
        var xml = @"<foo><bar>wtf</bar><bar>wtf2</bar></foo>";
        XmlReader xmlReader = XmlReader.Create(new MemoryStream(Encoding.UTF8.GetBytes(xml)));

        int count = 0;
        xmlReader.MoveToContent();
        while (xmlReader.Read())
        
            if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.Name == "bar")
            
                var element = xmlReader.ReadOuterXml();
                Console.WriteLine("just got an " + element);
                count++;
            
        
        Assert.AreEqual(2, count);
    

【问题讨论】:

使用ReadToFollowing("bar") 代替Read() 可以显着优化循环(也适用于Jon 的回答)。 我有一个类似的情况,我在 while 循环中使用 ReadToFollowingWhileReadOuterXml。如果文档使用换行符格式化,则它可以正常运行。当我有一个单行文档时,它会跳过以下所有节点。 【参考方案1】:

您正在调用ReadOuterXml,它将使用该元素并将“光标”放置在下一个元素之前。然后您再次调用Read,这会将光标移动到(例如,移动到元素内的文本节点)。

这是循环的替代方案:

while (!xmlReader.EOF)

    Console.WriteLine(xmlReader.NodeType);
    if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.Name == "bar")
    
        var element = xmlReader.ReadOuterXml();
        Console.WriteLine("just got an " + element);
        count++;                
    
    else
    
        xmlReader.Read();
    

【讨论】:

哦,那种“差一点”的感觉……再次感谢!【参考方案2】:

您是否可能通过在 while 循环条件中调用 Read() 函数,然后在循环本身中调用 ReadOuterXml() 函数来跳过一行?

【讨论】:

以上是关于如果没有空格分隔符,为啥 XmlReader 会跳过所有其他元素?的主要内容,如果未能解决你的问题,请参考以下文章

XmlReader 跳过相邻元素

NodeJS:为啥会跳过函数?

为啥在加载到 XMLTABLE 时会跳过 XML 文档的第 40,000 个字符?

为啥 XmlReader 中的默认编码与 XmlTextReader 默认编码的行为不同?

当堆栈仍然有元素时,为啥会跳过“如果堆栈不为空”条件?

如何在 PowerShell 中使用 XmlReader 流式传输大/巨大的 XML 文件?