Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to filter out XML nodes with Node.js?

I need to process a large KML file (>3 MiBs). To inspect it, I would need to look into it, but there is so many Style and StyleMap nodes that manual browsing becomes impossible. I have decided to remove the unnecessary nodes programmatically with Node.js. It is rather easy to parse an XML file with Node.js for example by using sax or xmldom. But the tricky part seems to be how to exclude certain nodes and their children and keep all the others. It becomes a rather complex task with sax because the output is XML so all kept nodes, their attributes and children must be processed. I feel there should be a simpler and more robust solution. Any suggestions and code snippets?

like image 585
Akseli Palén Avatar asked Oct 19 '25 05:10

Akseli Palén


1 Answers

One way is to use xmldom and xpath. First, fetch the nodes to remove by using xpath and XPath expressions. It returns an array of xmldom nodes that can be removed from the DOM tree. For example to remove all book nodes:

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);

However, dealing with namespaces, multiple XPath expressions, and indentation preservation is a struggle. Therefore I created a NPM module filterxml to lift the weights.

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

Will output:

<bookstore><essay>Reflections on Writing</essay></bookstore>
like image 80
Akseli Palén Avatar answered Oct 21 '25 19:10

Akseli Palén



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!