C# 为什么XmlReader会跳过元素?
请注意,此问题只针对C# 为什么XmlReader会跳过元素?,c#,.net,xmlreader,C#,.net,Xmlreader,请注意,此问题只针对XmlReader,而不是是否使用XDocument或XmlReader 我有一个XML片段,如下所示: private string GetXmlFragment() { return @"<bookstore> <book genre='novel' ISBN='10-861003-324'> <title>The Handmaid's Tale</title>
XmlReader
,而不是是否使用XDocument
或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>";
}
然而,我只得到第一个元素,调试表明,一旦我得到第一个元素,读者就会跳转到第二个book
元素的title
该解决方案的灵感来自
非常感谢您的帮助。问题是,如果没有中间空白,调用
XNode.ReadFrom()
将使XML读取器位于下一个元素的正位置。while
条件会在我们检查之前立即消耗该元素。修复方法是不立即调用XmlReader.Read()
,而是继续检查节点(因为读取是隐式完成的):
(如果不清楚,循环中的if
已更改为,而)公共静态IEnumerable GetElement(此XmlReader阅读器,string elementName)
{
而(!reader.EOF)
if(reader.NodeType==XmlNodeType.Element&&reader.Name==book)
返回XNode.ReadFrom(reader)作为XElement;
其他的
reader.Read();
}
代码会跳过其他每一个图书标签,因为图书标签会紧跟其后。read方法将阅读器留在下一个book标记处,然后read方法在读取第二个book标记之前移动,跳过元素。试试下面我开发的代码,它总是有效的
public static IEnumerable<XElement> GetElement(XmlReader reader, string elementName)
{
List<XElement> books = new List<XElement>();
while (!reader.EOF)
{
if(reader.Name != "book")
{
reader.ReadToFollowing("book");
}
if(!reader.EOF)
{
books.Add((XElement)XElement.ReadFrom(reader));
}
}
return books;
}
公共静态IEnumerable GetElement(XmlReader阅读器,string elementName)
{
列表书籍=新列表();
而(!reader.EOF)
{
if(reader.Name!=“book”)
{
读者。阅读以下内容(“书”);
}
if(!reader.EOF)
{
books.Add((XElement)XElement.ReadFrom(reader));
}
}
还书;
}
正如其他人所说,XNode.ReadFrom将您的读者推进到下一个图书打开标记(如果它们之间没有空格)然后reader.Read将推进到该标记的内部文本
有关更多信息,请参见此处:
修复您的扩展方法:
public static IEnumerable<XElement> GetElement(this XmlReader reader, string elementName)
{
reader.MoveToElement();
reader.Read();
while (!reader.EOF)
{
if (reader.NodeType == XmlNodeType.Element
&& reader.Name.Equals(elementName, StringComparison.InvariantCulture))
{
yield return XNode.ReadFrom(reader) as XElement;
}
else
{
reader.Read();
}
}
}
公共静态IEnumerable GetElement(此XmlReader读取器,string elementName)
{
reader.MoveToElement();
reader.Read();
而(!reader.EOF)
{
if(reader.NodeType==XmlNodeType.Element
&&reader.Name.Equals(elementName、StringComparison.InvariantCulture))
{
返回XNode.ReadFrom(reader)作为XElement;
}
其他的
{
reader.Read();
}
}
}
无法复制。您的方法在我的机器上生成一个包含两个元素的序列。您确定this.GetXmlFragment()
生成了您提供的XML吗?奇怪的是,我已经更新了这个问题,将方法包括在内,请参见。您的调试是否有干扰?Can confirm-方法按预期工作我忘了包含XmlReaderSettings
我已更新了问题,设置IgnoreWhitespace=false
行为正常,但将其设置为true
会导致跳转。
while (reader.Read()) {
while (reader.NodeType == XmlNodeType.Element
&& reader.Name.Equals(elementName, StringComparison.InvariantCulture)) {
yield return XNode.ReadFrom(reader) as XElement;
}
}
public static IEnumerable<XElement> GetElement(this XmlReader reader, string elementName)
{
while (!reader.EOF)
if (reader.NodeType == XmlNodeType.Element && reader.Name == "book")
yield return XNode.ReadFrom(reader) as XElement;
else
reader.Read();
}
public static IEnumerable<XElement> GetElement(XmlReader reader, string elementName)
{
List<XElement> books = new List<XElement>();
while (!reader.EOF)
{
if(reader.Name != "book")
{
reader.ReadToFollowing("book");
}
if(!reader.EOF)
{
books.Add((XElement)XElement.ReadFrom(reader));
}
}
return books;
}
public static IEnumerable<XElement> GetElement(this XmlReader reader, string elementName)
{
reader.MoveToElement();
reader.Read();
while (!reader.EOF)
{
if (reader.NodeType == XmlNodeType.Element
&& reader.Name.Equals(elementName, StringComparison.InvariantCulture))
{
yield return XNode.ReadFrom(reader) as XElement;
}
else
{
reader.Read();
}
}
}