XmlReader在一次读取文档时检索两组不同的元素

时间:2012-12-12 04:20:42

标签: xml performance xmlreader openstreetmap

我正在尝试阅读2.5GB XML文件并删除某些节点,比如说,“CD”元素和“DVD”元素。目前我正在做这样的事情:

using (XmlReader reader = XmlReader.Create("file.xml"))
{
    DeleteElements(reader.ReadElements("CD"));
    DeleteElements(reader.ReadElements("DVD")); // reader returns 0 elements
}

注意:DeleteElements只是循环这些元素并将其从文档中删除,但对于此问题而言,这主要是不重要的。

目前我发现没有检索到“DVD”元素。如果您之前使用过XmlReader,我相信您可以在此处找出问题的原因:读者在读取“CD”节点的文档后,读者找不到任何“DVD” “元素因为读者位于文档的末尾。

考虑到XML文件的大小以及我想要检索的元素数量,我无法将整个文档加载到内存中,因为你得到OutOfMemoryException - 这意味着没有XDocument或XPathDocument善良。

有没有办法让XmlReader在读取文档时返回“CD”和“DVD”?最初加载文档非常耗时,所以我不想多次这样做。像reader.ReadElements("DVD|CD")这样令人敬畏的东西将是 sweet

1 个答案:

答案 0 :(得分:2)

XmlReader是一个仅向前xml解析器。如果有一个ReadElements方法,它会将读者运行到最后,然后就不再有DVD元素了。所以你必须在文件上运行两次。

XmlReader的基本用法:

using (XmlReader reader = XmlReader.Create("input.xml")) {
  while (reader.Read()) {
    switch (reader.NodeType) {
    case XmlNodeType.Element:
      switch (reader.Name) {
      case "CD":
        // do something with a CD
        break;
      case "DVD":
        // do something with a DVD
        break;
      default:
        // do something with all other elements
        break;
      }
      break;
    }
  }
}

您在DeleteElements方法中做了什么?您可能需要为新的临时文件创建一个XmlWriter,然后将之外的所有元素删除写入临时文件,并至少替换带有临时文件的原始文件。

通过这种方式,您可以对所有元素进行一次循环,包括删除(排除)某些元素。