【问题标题】:Parsing large xml files (1G+) in node.js在 node.js 中解析大型 xml 文件 (1G+)
【发布时间】:2019-02-18 06:10:50
【问题描述】:

我很难找到可以解析 1G+ 大小的大型 xml 文件的节点包。我们的后端服务器主要是 node.js,所以我不希望不得不用另一种语言/平台构建另一个服务来解析 xml 并将数据写入数据库。有没有人在节点中成功地做这种事情?你用了什么?我看过一堆包,如 xml-stream、big-xml 等,它们都有自己的问题。有些甚至无法在 mac 上编译(并且似乎已过时且不再受支持)。我真的不需要将解析结果转换为 js 对象或类似的东西。只需要理解数据,然后写入数据库。

【问题讨论】:

  • 是的,我也在寻找可以与我的scramjet framework 一起使用的东西——这可能是您可能想要在后面的步骤中使用的东西,但应该使用“sax”之类的东西处理器...
  • 你检查过这个吗? github.com/isaacs/sax-js.
  • @MichałKapracki 是的,我试过萨克斯,但使用起来似乎很慢而且很麻烦。
  • 嗯...奇怪。据我所知,sax 实际上比 libxml 快。我现在没有时间,但我会检查并尝试根据需要将一些样本与超燃冲压发动机耦合,并将我的发现发布在解析器上......

标签: node.js xml xml-parsing filestream


【解决方案1】:

最明显但不是很有帮助的答案是它取决于要求。

但是,在您的情况下,这似乎很简单;您需要加载可能适合也可能不适合内存的大块数据,以便在将其写入数据库之前进行简单处理。我认为这就是为什么您希望将 CPU 作为单独的进程外部化的一个很好的理由。因此,首先关注哪个 XML 解析器为您完成这项工作可能更有意义,而不是您想要使用哪个 Node 包装器。

显然,任何需要在处理之前将整个文档加载到内存中的解析器都不是一个有效的选项。您需要为此使用流和支持这种顺序处理的解析器。

这给您留下了几个选择:

Saxon 似乎对最近的 W3C 规范具有最高的一致性,因此如果模式验证等比这更重要,那么它可能是一个不错的候选者。否则 Libxml 和 Expat 似乎都是 stack up pretty well performance wise 并且已经预装在大多数操作系统上。

可用于所有这些的 Node 包装器:

我的 Node 实现如下所示:

import * as XmlStream from 'xml-stream'
import { request } from 'http'
import { createWriteStream } from 'fs'

const xmlFileReadStream = request('http://external.path/to/xml')
const xmlFileWriteStream = new XmlStream(xmlFileReadStream)
const databaseWriteStream = createWriteStream('/path/to/file.csv')

xmlFileWriteStream.on('endElement: Person', ({ name, phone, age }) =>
  databaseWriteStream.write(`"${name}","${phone}","${age}"\n`))

xmlFileWriteStream.on('end', () => databaseWriteStream.end())

当然我不知道你的数据库写入流会是什么样子,所以这里我只是将它写入一个文件。

【讨论】:

  • 嘿 :) 如果你不知道 'person' 节点存在 - 你如何解析这个 xml?
猜你喜欢
  • 2015-09-15
  • 2011-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多