是否有可能克隆xmlTextReader(或多遍读取)?

时间:2013-03-25 08:14:23

标签: c xml xml-parsing libxml2 xmlreader

我目前必须修复现有应用程序以使用DOM interface libxml2以外的其他内容,因为事实证明它传递的XML文件太大而无法加载到内存中。< / p>

我已经重复了从迭代DOM树到大部分时间使用xmlTextReader的数据加载,而没有太多问题。 (我使用xmlNewTextReaderFilename打开本地文件。)

然而,事实证明,大数据所在的子树必须不按顺序读取,但我必须先收集一些(少量)数据。 (问题正是这个子树包含大量数据,所以只将这个子树加载到内存中也没有多大意义。)

最简单的方法就是“克隆”/“复制”我当前的读者,提前读取然后返回原始实例继续阅读。 (似乎我not the first one ......在C#方面甚至实现了一些东西:XML Reader with Bookmarks。)

然而,似乎没有办法“复制”xmlTextReader的状态。

如果我无法重新读取文件的部分,我还可以重新阅读整个文件,虽然这很浪费,但在这里可以,但是我还需要记住我之前的位置吗?

是否有一种简单的方法可以记住xmlTextReader在当前文档中的位置,以便稍后在第二次阅读文档/文件时再次找到该位置?

这是一个问题示例:

<root>
  <cat1>
    <data attrib="x1">
      ... here goes up to one GB in stuff ...
    </data>
    <data attrib="y2"> <!-- <<< Want to remember this position without having to re-read the stuff before -->
      ... even more stuff ...
    </data>
    <data attrib="z3">
       <!-- I need (part of) the data here to meaningfully interpret the data in [y2] that 
            came before. The best approach would seem to first skip all that data
            and then start back there at <data attrib="y2"> ... not having to re-read
            the whole [x1] data would be a big plus! -->
    </data>
  </cat1>
  ...
</root>

1 个答案:

答案 0 :(得分:1)

我想从我learned at the XML mailing list

中给出一个解决方法的答案

没有简单的方法可以在xmlReader上“克隆”状态,但是应该可以做什么,也应该很简单就是计算文档上的读取数。

也就是说,要使用xmlReader读取文档,您必须调用以下内容:

// looping ...
status = ::xmlTextReaderRead(pReader);

如果您以结构化方式执行此操作(例如,我最终编写了一个封装我的xmlReader使用模式的封装类),则添加计数器相对容易:

// looping ...
status = ::xmlTextReaderRead(pReader);
if (1 == status) { // success
  ++m_ReadCounter;
}

要重新阅读文档(到达某个位置),您只需致电xmlTextReaderRead多次m_ReadCounter次,弃置结果,直至到达您想要重新开始的位置。

是的,您必须重新解析整个文档,但这可能足够快。 (实际上可能比缓存文档的大量部分更好/更快。)