我试图解析XML文件并从元素中提取数据。问题是每次我使用ReadElementContentAsX时,读者都会跳过下一个元素。我不知道为什么会这样。我错过了什么?
while (reader.Read() && fileValid)
{
if (reader.IsStartElement())
{
Console.WriteLine(reader.Name);
switch (reader.Name)
{
case "ID": if (reader.ReadElementContentAsString() != ID)
{
fileValid = false;
} break;
case "Size":
if (reader.ReadElementContentAsInt() != EEPROM_SIZE)
{
fileValid = false;
}
break;
case "Data": if (reader.ReadElementContentAsBase64(eeprom_primary, 0, EEPROM_SIZE) != EEPROM_SIZE)
{
fileValid = false;
}
break;
default:
break;
}
}
}
XML结构如下:
-ParrentNode
--ID:String
--Date:TimeDate
--SoftwareVersionMajor:int
--SoftwareVersionMinor:int
--Size: int
--Data: encodedBase64
所以在我的情况下,我读取元素ID,大小的元素内容。它将跳过元素日期和数据。我检查了是否删除了readElementContentAs,它不会跳过下一个节点
来自MSND(ReadElementContentAs):
“此方法读取开始标记,元素的内容,并将读者移动到结束元素标记之外。”
该方法旨在跳到您的下一个元素。
编辑:
您可以使用XmlDocument尝试:
XmlDocument xmlDoc = new XmlDocument();
loadXML(xmlDoc, "inputfile.xml");
然后,您可以使用Xpath表达式和每个循环轻松处理Xml文件:
foreach (XmlNode node in xmlDoc.SelectNodes("/src"))
{
// do anything with node
}
从ReadElementContentAsString
的文档:
此方法读取开始标记,元素的内容,并将读取器移动到结束元素标记之外。
所以你最终会在下一个元素的开头。然后再次调用Read()
,它会跳过该元素的开头,或者跳过整个元素,或者“移入”它以使IsStartElement()
返回false。所以基本上,如果你使用了Read()
,你不想在循环开始时调用ReadElementContentAs*
。
这就是为什么我讨厌XmlReader
。除非你真的需要使用它,否则我强烈建议使用LINQ to XML将整个文档读入内存。即使你确实需要使用XmlReader
,你仍然可以一次读取一个元素到LINQ to XML,以一种“有点流式”的方式,最大限度地减少你对阅读器部分的曝光。
哼。好的想通了自己。只是更改了reader.Read()in条件到!reader.EOF并改变了一下我的阅读方式。现在有效。谢谢您的帮助 :)
对于任何想要因任何原因使用XmlReader的人来说,XmlReader.ReadString()似乎与XmlReader.ReadElementContentAsString()没有相同的问题。我只是不知道它是否也会扩展实体并跳过处理说明和评论,因为我不必为此目的而担心这一点。