1

下面的原始问题,有关解决方案的更新,如果有人有类似的问题:

对于一个快速的正则表达式,我找到了http://re2c.org/;用于 xml 解析http://expat.sourceforge.net/


是否有一个 xml 库可以用来在 c 中以流式方式从内存(而不是文件)中解析 xml?

目前我有:

  • libxml2 ; XMLReader 似乎只能与文件句柄一起使用,而不能在内存中使用
  • rapidxml 是 c++ 并且似乎没有暴露 ac 接口

要求:

  • 我需要处理单个 xml 节点,而不需要将整个 xml(400GB 未压缩,并且“仅”29GB 作为原始 .bz2 文件)在内存中(bzip'd 文件被读取并分段解压缩,我会将这些未压缩的部分传递给由 xml 解析器使用)
  • 它不需要非常快,但我更喜欢一个有效的解决方案
  • 我(很可能)不需要提取节点的路径,所以只要它们被我的回调处理就丢弃它们就可以了(如果我需要与我现在想的相反的路径,然后我仍然可以自己跟踪它)

这是我试图解决我自己在此处发布的问题的一部分(不,这不是同一个问题):如何在 C 中有效地解析大型 bz2 xml 文件

理想情况下,我希望能够一次向库提供一定数量的字节,并在节点完成时调用一个函数。

非常感谢


这是一些伪 c 代码(比实际 c 代码短得多)以便更好地理解

// extracted data gets put here
strm.next_out = buffer_ptr;

while( bytes_processed_total < filesize ) {

  // extracts up to amount of data set in strm.avail_in
  BZ2_bzDecompress( strm );

  bytes_processed = strm.next_out - buffer_ptr;
  bytes_processed_total += bytes_processed;

  // here I would like to pass bytes_processed of buffer_ptr to xmlreader

}

关于我要解析的数据:http ://wiki.openstreetmap.org/wiki/OSM_XML

目前我只需要其中的某些<node ...>节点,这些节点具有子节点<tag k="place" v="country|county|city|town|village">('|' 表示在这种情况下至少有一个,在文件中当然只有“国家”等没有“|”)

4

1 回答 1

2

来自 libxml2 的 xmlReaderForMemory 对我来说似乎是一个不错的选择(但没有使用它,我可能错了)

char * 缓冲区需要指向一个有效的 XML 文档(可以是整个 XML 文件的一部分)。这可以提取成块读取您的文件,但获得有效的 XML 片段。

您的 XML 文件的结构是什么?包含后续相似节点的根或完全成熟的树?

如果我有这样的 XML:

<root>
<node>...</node>
<node>...</node>
<node>...</node>
</root>

我会从开头读到<node>结尾</node>,然后用 xmlReaderForMemory 函数解析它,做我需要做的,然后继续下一个<node>节点。

Ofc 如果你的<node>内容太复杂/太长,你可能需要深入一些层次:

<node>
<subnode>....</subnode>
<subnode>....</subnode>
<subnode>....</subnode>
<subnode>....</subnode>
</node>

并从文件中读取,直到你拥有整个<subnode>节点(但要跟踪你在<node>.

我知道这很丑陋,但这是一种可行的方式。或者您可以尝试使用 sax 解析器(不知道是否存在某些 C 实现)。

Sax 解析会在每个节点开始和节点结束时触发事件,因此在找到节点并仅处理它们之前,您什么也做不了。

另一种可行的方法是使用一些外部工具来过滤整个 XML(XQuery 或 XPath 处理器),以便从整个文件中仅提取您感兴趣的节点,获取一个较小的文档,然后对其进行处理。

编辑:Zorba 是一个很好的 XQuery 框架,带有命令行预处理器,可能是一个很好的地方

EDIT2:既然你有这个尺寸,一种替代解决方案可以将文件作为文本文件管理,因此读取和解压缩块,然后匹配如下内容:

<yourNode>.*</yourNode>

用正则表达式。

如果你在 Linux/Unix 上,你应该有 POSIX 正则表达式库。在 SO 上查看
此问题以获取更多见解。

于 2013-08-29T13:46:02.040 回答