虽然试图尽量减少XML解析程序的内存占用,特别是避免使用XElement.Load()
加载数百兆字节,但是我遇到了使用较旧的XmlReader
e.g. here的文章。XmlReader跳过相邻元素
我需要在内部重建每个主要元素为XElement
以避免重大重构。但是,我发现如果我的源元素直接相邻,则此方法会跳过每个第2个元素。
我拆掉了问题该单元测试(MSTest2与FluentAssertions):
[DataTestMethod]
[DataRow("<data><entry>1</entry><entry>2</entry><entry>3</entry><entry>4</entry></data>")]
[DataRow("<data><entry>1</entry> <entry>2</entry> <entry>3</entry> <entry>4</entry></data>")]
public void XmlReaderCount(string input)
{
var sr = new StringReader(input);
var xml = XmlReader.Create(sr);
xml.MoveToContent();
var data = new List<string>();
while (xml.Read())
{
if (xml.LocalName == "entry" && xml.NodeType == XmlNodeType.Element)
{
var element = (XElement)System.Xml.Linq.XNode.ReadFrom(xml);
data.Add(element.Value);
}
}
data.Should()
.HaveCount(4);
}
第一(数据驱动的)测试失败:
预计集合包含4个项目,但找到了2.
因为它将1和3放入数据收集中。它循环4次,但每个其他元素都有xml.NodeType
的Text
,而不是Element
。通过处理所有4
在我的现实世界的例子第二次测试(与</entry>
和<entry>
通过之间的空间,我不能轻易改变的源泉。我已经有一个解决方案,通过another StackOverflow question启发,所以我可以做下面,但它似乎很奇怪 - 一些错误
[DataTestMethod]
[DataRow("<data><entry>1</entry><entry>2</entry><entry>3</entry><entry>4</entry></data>")]
[DataRow("<data><entry>1</entry> <entry>2</entry> <entry>3</entry> <entry>4</entry></data>")]
public void XmlReaderCountSubtree(string input)
{
var data = new List<string>();
var sr = new StringReader(input);
var xml = XmlReader.Create(sr);
xml.MoveToContent();
while (xml.Read())
{
if (xml.LocalName == "entry" && xml.NodeType == XmlNodeType.Element)
{
using (var subtree = xml.ReadSubtree())
{
subtree.MoveToContent();
var content = subtree.ReadOuterXml();
var element = XElement.Parse(content);
data.Add(element.Value);
}
}
}
data.Should()
.HaveCount(4);
}
啊,疑难杂症。因此,在if条件中,我会调用'continue',否则(不需要else)我会执行'xml.Read()'来执行类似于你的操作。 –