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

我目前必须修复现有的应用程序以使用libxml2的DOM接口以外的东西,因为事实certificate它传递的XML文件太大而无法加载到内存中。

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

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

最简单的方法就是“克隆”/“复制”我当前的读者,提前读取然后返回原始实例继续阅读。 (似乎我不是第一个 ……在C#方面甚至实现了一些东西: 带有书签的XML阅读器 。)

但是,似乎没有任何方法可以“复制”xmlTextReader的状态。

如果我不能重新读取文件的一部分 ,我也可以重新读取整个文件,虽然这很浪费,但在这里也可以,但我仍然需要记住我之前的位置?

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

这是一个问题的例子:

    ... here goes up to one GB in stuff ...   <!-- << ... even more stuff ...   <!-- 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  ... not having to re-read the whole [x1] data would be a big plus! -->   ...  

我想从我在XML邮件列表中学到的内容中给出一​​个解决方法的答案:

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

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

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

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

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

要重新读取文档(到达某个位置),您只需调用xmlTextReaderRead多次m_ReadCounter次,丢弃结果,直到到达想要重新开始的位置。

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