c#XMLReader在使用ReadElementContentAs后跳过节点

时间:2014-07-28 08:30:49

标签: c# xml xml-parsing xmlreader

我正在尝试解析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它不会跳过下一个节点

4 个答案:

答案 0 :(得分:4)

来自ReadElementContentAsString的文档:

  

此方法读取开始标记,元素的内容,并将阅读器移动到结束元素标记之外。

所以你最终会在下一个元素的开头。然后再次调用Read(),它会移动过去该元素的开头,或者跳过整个元素或者“移入”它以使IsStartElement()返回false。所以基本上,如果您使用Read(),则不希望在循环开始时调用ReadElementContentAs*

这就是我讨厌XmlReader的原因。除非你真的需要使用它,否则我强烈建议使用LINQ to XML将整个文档读入内存。即使你需要使用XmlReader,你仍然可以一次读取一个元素到LINQ to XML,以某种“有点流式”的方式,最大限度地减少你对读者的曝光一部分。

答案 1 :(得分:4)

来自MSND(ReadElementContentAs):

"此方法读取开始标记,元素的内容,并将阅读器移动到结束元素标记之外。"

该方法旨在跳到您的下一个元素。

编辑:

您可以使用XmlDocument尝试:

  XmlDocument xmlDoc = new XmlDocument();
  loadXML(xmlDoc, "inputfile.xml");

然后,您可以使用Xpath表达式和每个循环轻松处理Xml文件:

  foreach (XmlNode node in xmlDoc.SelectNodes("/src"))
  {
    // do anything with node
  }

答案 2 :(得分:0)

HMM。好的想通了自己。只是更改了reader.Read()in条件到!reader.EOF并改变了一下我的阅读方式。现在有效。感谢您的帮助:)

答案 3 :(得分:0)

对于出于任何原因想要使用XmlReader的任何人,XmlReader.ReadString()似乎都没有与XmlReader.ReadElementContentAsString()相同的问题。我只是不知道它是否还会扩展实体并跳过处理指令和注释,因为我不必为此担心。