下面是原始问题,如果有人遇到类似问题,请更新有关解决方案:
对于快速正则表达式,我找到了 http://re2c.org/ ;用于 xml 解析 http://expat.sourceforge.net/
是否有一个 xml 库可以用来在 c 中以流方式从内存(而不是文件)解析 xml?
目前我有:
- libxml2 ; XMLReader 似乎只能与文件句柄一起使用,而不是在内存中使用
- rapidxml 是 c++ 并且似乎没有公开 c 接口(interface)
要求:
- 我需要处理单个 xml 节点,而不需要将整个 xml(400GB 未压缩,“只有”29GB 作为原始 .bz2 文件)存储在内存中(bzip 文件被读入并分段解压,我会传递那些xml 解析器使用的未压缩片段)
- 不需要非常快,但我更喜欢高效的解决方案
- 我(很可能)不需要提取节点的路径,所以只要它们被我的回调处理过就丢弃它们就可以了(如果我需要与我想的相反的路径现在,我仍然可以自己追踪它)
这是我试图解决我自己的问题的一部分(不,这不是同一个问题):How to efficiently parse large bz2 xml file in C
理想情况下,我希望能够一次为库提供一定数量的字节,并在节点完成时调用一个函数。
非常感谢
为了更好地理解,这里有一些伪 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">
(“|”在此上下文中至少表示其中一个,在文件中它当然只是“国家”等而没有“|”)
最佳答案
libxml2 中的 xmlReaderForMemory 对我来说似乎是个不错的选择(但还没有用过,我可能错了)
char * 缓冲区需要指向一个有效的 XML 文档(它可以是整个 XML 文件的一部分)。这可以提取成 block 读取您的文件,但获得有效的 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:好吧,既然你有这个维度,一个替代解决方案可以将文件作为文本文件来管理,所以读取和解压缩 block ,然后匹配类似的东西:
<yourNode>.*</yourNode>
使用正则表达式。
如果您使用的是 Linux/Unix,您应该拥有 POSIX 正则表达式库。检查
this question on S.O.以获得进一步的见解。
关于c - 在 C 中以流方式读取和处理内存中的 XML 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18512207/