在node.js中解析大型xml文件(1G +)

时间:2018-09-13 13:33:52

标签: node.js xml xml-parsing filestream

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

1 个答案:

答案 0 :(得分: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())

我当然不知道您的数据库写流是什么样子,所以在这里我只是将其写到文件中。