如何用Node.js过滤掉XML节点?

如何用Node.js过滤掉XML节点?

问题描述:

我需要处理一个大的KML文件(> 3 MiBs)。为了检查它,我需要研究它,但是有很多Style和StyleMap节点,使得手动浏览变得不可能。我决定用Node.js编程删除不必要的节点。使用Node.js解析XML文件相当容易,例如使用saxxmldom。但棘手的部分似乎是如何排除某些节点和他们的孩子,并保留所有其他节点。由于输出是XML,所以所有保留的节点,它们的属性和子节点都必须被处理,因此它变成一个相当复杂的任务sax。我觉得应该有一个更简单,更强大的解决方案。任何建议和代码片段?如何用Node.js过滤掉XML节点?

+2

上搜索NPM任何XML解析器包,包括它,看了你的文件,删除某些节点,保存到文件就万事大吉了。你到底在问什么? – xDreamCoding

+0

@xDreamCoding谢谢,我一直在寻找一个通用的方法,你简要描述了一下,并且有一个代码片断。尤其是节点应该如何移除的部分。我编辑了更具体的问题。我发现[xpath](https://www.npmjs.com/package/xpath)可能能够做到这一点。如果它运行良好,我想我会为此实现一个npm模块。 –

+0

您想要转换XML文件。 XSLT是你的朋友。 – Tomalak

一种方法是使用xmldomxpath。首先,使用xpath和XPath表达式来获取要删除的节点。它返回一个可以从DOM树中移除的xmldom节点数组。例如,要删除所有book节点:

var xmldom = require('xmldom'); 
var xpath = require('xpath'); 

var parser = new xmldom.DOMParser(); 
var serializer = new xmldom.XMLSerializer(); 

var xmlIn = '<bookstore>' + 
    '<book>Animal Farm</book>' + 
    '<book>Nineteen Eighty-Four</book>' + 
    '<essay>Reflections on Writing</essay>' + 
    '</bookstore>'; 

var root = parser.parseFromString(xmlIn, 'text/xml'); 

var nodes = xpath.select('//book', root); 

nodes.forEach(function (n) { 
    n.parentNode.removeChild(n); 
}); 

var xmlOut = serializer.serializeToString(root); 

然而,处理命名空间,多XPath表达式和缩进保存是一个斗争。因此我创建了一个NPM模块filterxml来提升重量。

var filterxml = require('filterxml') 
var patterns = ['//book']; 
var namespaces = {}; 
filterxml(xmlIn, patterns, namespaces, function (err, xmlOut) { 
    console.log(xmlOut); 
}); 

将输出:

<bookstore><essay>Reflections on Writing</essay></bookstore>