【问题标题】:node.js - extract XML fragments from large XML filesnode.js - 从大型 XML 文件中提取 XML 片段
【发布时间】:2016-01-11 12:46:57
【问题描述】:

我在一个 node.js 应用程序上工作,用于处理大量地理空间数据并将其从文件加载到 JSON 文档数据库中。

源数据采用大型(最多 10 GB)XML 文档的形式。我使用sax.js 来解析源文档,这为我提供了代表 XML 结构的 JavaScript 对象:

{ name: 'gml:featureMember',
  attributes: {},
  isSelfClosing: false,
  parent: null,
  children: 
   [ '\r\n        ',
     { name: 'AX_BesondereFlurstuecksgrenze',
       attributes: { 'gml:id': 'DEHHALKAn0007s8z' },
       isSelfClosing: false,
       children: 
        [ '\r\n          ',
          { name: 'gml:identifier',
            attributes: { codeSpace: 'http://...' },
            isSelfClosing: false,
            children: [ 'urn:adv:oid:...' ] },
          '\r\n          ',
          { name: 'lebenszeitintervall',
            attributes: {},
            isSelfClosing: false,
            children: 
             [ '\r\n            ',
               { name: 'AA_Lebenszeitintervall',
                 attributes: {},
                 isSelfClosing: false,
                 children: 
                  [ '\r\n              ',
                    { name: 'beginnt',
                      attributes: {},
                      isSelfClosing: false,
                      children: [ '2010-03-07T08:32:05Z' ] },
                    '\r\n            ' ] },
               '\r\n          ' ] },
          ...

但是,sax.js 显然无法访问当前片段。所以我正在寻找一种从 sax.js 或不同的流解析器获取 XML 片段的方法。由于我在 Windows 上,我只想使用不需要编译的模块。

【问题讨论】:

  • 您可以尝试使用 XPath/Xquery。
  • 是否有仅基于 sax.js 且不需要编译的 xpath/yquery 实现?我简要查看了 saxtract 和其他,但它们似乎都使用 libxmljs。
  • 只获取XML片段,可以直接在javascript中使用XPath。这里给出了很好的介绍:timkadlec.com/2008/02/xpath-in-javascript-introduction
  • @Jagrut 我看到 node.js 也有一个纯 javascript 实现的 Xpath 以及npmjs.com/package/xpath.js(),但它需要一个 DOM 解析器。我不认为我可以将 DOM 解析器用于几千兆字节的 XML 文件。
  • 好的,我遵循 Xpath 路径并能够使用 npmjs.com/package/saxpath 解决问题。处理 1.7GB 文件时,节点中的内存使用量保持在 70MB 以下,但处理过程中存在一些较长的(垃圾收集?)延迟。

标签: javascript xml node.js


【解决方案1】:

根据@Jagrut 的建议,我搜索了适用于 sax.js 且不需要 DOM 或本机库的 node.js 的 XPath 实现。我发现saxpath 符合要求。

用法如下:

var fs = require('fs');
var saxParser = require('sax').createStream(true);
var saxPath = require('saxpath');

var dataURL = '../data/ALKIS_FHH_0167.xml';
var count = 0;

parseXML(dataURL);

function parseXML(fileName) {

    var fileStream = fs.createReadStream(fileName);
    var streamer = new saxPath.SaXPath(saxParser, '//gml:featureMember');

    streamer.on('match', function(xml) {
        addFeature(xml);
    });

    fileStream.pipe(saxParser);
}

function addFeature (featureFragment) {
    // for now we just count features...
    if (count % 100 == 0) {
        console.log("Parsing fragment " + count);
    }
    count++;
}

它有一个比直接使用 sax.js 更好的 API。我注意到的唯一警告是解析有时会停止几秒钟,可能是由于 GC。我用最大 1.7GB 的 XML 文件对此进行了测试。

【讨论】:

  • 我对 saxpath 不太了解,但是您能不首先加载整个 XML,而是直接在文档上应用 XPath 然后解析它吗?我不确定,只是一个想法!
猜你喜欢
  • 2015-09-15
  • 1970-01-01
  • 2014-05-20
  • 2011-01-23
  • 2019-02-18
  • 2016-01-18
  • 2014-11-16
  • 1970-01-01
  • 2013-01-28
相关资源
最近更新 更多