为什么XmlReader跳过元素? [英] Why is the XmlReader skipping elements?

查看:60
本文介绍了为什么XmlReader跳过元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请注意,此问题特定于 XmlReader ,而不是使用 XDocument 还是 XmlReader .

Please note this question is specific to XmlReader and not whether to use XDocument or XmlReader.

我有一个 XML 片段:

private string GetXmlFragment()
{
    return @"<bookstore>
          <book genre='novel' ISBN='10-861003-324'>
            <title>The Handmaid's Tale</title>
            <price>19.95</price>
          </book>
          <book genre='novel' ISBN='1-861001-57-5'>
            <title>Pride And Prejudice</title>
            <price>24.95</price>
          </book>
        </bookstore>";
}

我还有一个扩展方法,例如:

I also have an extension method as:

public static IEnumerable<XElement> GetElement(this XmlReader reader, string elementName)
{
    reader.MoveToElement();

    while (reader.Read())
    {
        if (reader.NodeType == XmlNodeType.Element 
            && reader.Name.Equals(elementName, StringComparison.InvariantCulture))
        {
            yield return XNode.ReadFrom(reader) as XElement;
        }
    }
}

然后我尝试通过以下操作获得两个 book 元素:

I then try to get the two book elements by doing:

var xmlReaderSettings = new XmlReaderSettings
{
    CheckCharacters = false,
    ConformanceLevel = ConformanceLevel.Fragment,
    IgnoreComments = true,
    IgnoreWhitespace = true,
    IgnoreProcessingInstructions = true
};

using (var stringReader = new StringReader(this.GetXmlFragment()))
using (var xmlReader = XmlReader.Create(stringReader, xmlReaderSettings))
{
    xmlReader.GetElement("book").Count().ShouldBe(2);
}

但是,我只得到第一个元素,调试显示,只要得到第一个元素,读者就会跳到第二个 book 元素的 title .

However I only get the first element, debugging shows that as soon as I get the first element the reader jumps to the title of the second book element.

该解决方案的灵感来自

The solution is inspired from HERE

非常感谢您的帮助.

推荐答案

问题是,如果没有中间的空格,则对 XNode.ReadFrom()的调用将使XML阅读器定位就在下一个元素.然后, while 条件会立即使用此元素,然后我们才能对其进行检查.解决方法是不要在此之后立即调用 XmlReader.Read(),而是继续检查节点(因为读取已隐式完成):

The problem is that, if there is no intervening whitespace, the call to XNode.ReadFrom() will leave the XML reader positioned right at the next element. The while condition then immediately consumes this element before we can check it. The fix is to not call XmlReader.Read() immediately afterwards, but to continue checking for nodes (as the read has been done implicitly):

while (reader.Read()) {
    while (reader.NodeType == XmlNodeType.Element 
           && reader.Name.Equals(elementName, StringComparison.InvariantCulture)) {
        yield return XNode.ReadFrom(reader) as XElement;
    }
}

(如果不清楚,则循环中的 if 已更改为 while .)

(In case it's not clear, the if in the loop has been changed to a while.)

这篇关于为什么XmlReader跳过元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆