C# XmlReader跳过相邻元素

C# XmlReader跳过相邻元素,c#,xml-parsing,C#,Xml Parsing,在尝试最小化XML解析程序的内存占用的同时,特别是避免使用XElement.Load()加载数百兆字节,我看到一些文章建议使用较旧的XmlReader 我需要在内部将每个主要元素重构为XElement,以避免主要重构。然而,我发现,如果我的源元素是直接相邻的,那么这种方法会跳过第二个元素 我已经解决了这个单元测试的问题(带有FluentAssertions的MSTest2): [DataTestMethod] [数据行(“1234”)] [数据行(“1234”)] 公共无效XmlReaderCo

在尝试最小化XML解析程序的内存占用的同时,特别是避免使用
XElement.Load()
加载数百兆字节,我看到一些文章建议使用较旧的
XmlReader

我需要在内部将每个主要元素重构为
XElement
,以避免主要重构。然而,我发现,如果我的源元素是直接相邻的,那么这种方法会跳过第二个元素

我已经解决了这个单元测试的问题(带有FluentAssertions的MSTest2):

[DataTestMethod]
[数据行(“1234”)]
[数据行(“1234”)]
公共无效XmlReaderCount(字符串输入)
{
var sr=新的StringReader(输入);
var xml=XmlReader.Create(sr);
xml.MoveToContent();
var data=新列表();
while(xml.Read())
{
if(xml.LocalName==“entry”&&xml.NodeType==XmlNodeType.Element)
{
var element=(XElement)System.Xml.Linq.XNode.ReadFrom(Xml);
数据。添加(元素。值);
}
}
data.Should()
.HaveCount(4);
}
第一次(数据驱动)测试失败,原因是:

预期集合包含4项,但找到2项

因为它将1和3放入数据收集中。它确实循环了4次,但其他每个元素都有一个
xml.NodeType
Text
,而不是
element
。第二个测试(在
之间有空格)通过处理所有4个测试

在我的现实世界的例子中,我不能轻易地更改源代码。我已经有了一个解决方案,受此启发,我可以执行以下操作,但这似乎很奇怪——有什么问题吗

[DataTestMethod]
[数据行(“1234”)]
[数据行(“1234”)]
公共void XmlReaderCountSubtree(字符串输入)
{
var data=新列表();
var sr=新的StringReader(输入);
var xml=XmlReader.Create(sr);
xml.MoveToContent();
while(xml.Read())
{
if(xml.LocalName==“entry”&&xml.NodeType==XmlNodeType.Element)
{
使用(var subtree=xml.ReadSubtree())
{
subtree.MoveToContent();
var content=subtree.ReadOuterXml();
var元素=XElement.Parse(内容);
数据。添加(元素。值);
}
}
}
data.Should()
.HaveCount(4);
}

当您调用
ReadFrom(xml)
时,xml的状态会发生变化。它的光标会向前移动到下一个元素。然后,您的代码会移动到
,而(xml.Read())
会完全忽略该新元素

对于第二个数据集,被忽略(和未被检查)的元素是空白节点,因此可以忽略它。但基本上,读取算法是错误的

为您的第一种方法提供了一个修复方案,虽然不美观,但效果良好:

xml.Read();
while (! xml.EOF)
{
    if (xml.LocalName == "entry" && xml.NodeType == XmlNodeType.Element)
    {
        //using (var subtree = xml.ReadSubtree())
        {                    
            var element = (XElement)XNode.ReadFrom(xml);
            data.Add(element.Value);
        }
    }
    else
    {
        xml.Read();
    }
}

啊,明白了。所以在(!xml.EOF)的同时,在if条件中,我将调用
continue
,否则(不需要else)我将执行
xml.Read()