最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

XML to JSON - dealing with xml namespaces and alias in JavaScript - Stack Overflow

programmeradmin2浏览0评论

I am trying to convert XML to JSON in node.js using the module xml2js. How do I handle the namespace alias when accessing variables?

The follow code converts my file (sampleWithNamespaces.xml)

var fs = require('fs'),
xml2js = require('xml2js');

var parser = new xml2js.Parser();
fs.readFile('sampleWithNamespaces.xml', function (err, data) {
    parser.parseString(data, function (err, result) {
        console.dir(result);
        console.log('Done');
    });
});

sampleWithNamespaces.xml :

<d:student xmlns:d=''>
  <d:id>3235329</d:id>
  <d:name>Jeff Smith</d:name>
  <d:language>JavaScript</d:language>
  <d:rating>9.5</d:rating>
</d:student>

Output:

$ node xml2jsTest.js
{ '@': { 'xmlns:d': '' },
  'd:id': '3235329',
  'd:name': 'Jeff Smith',
  'd:language': 'JavaScript',
  'd:rating': '9.5' }
Done

I can access the 'name' attribute by using the notation result['d:name'] instead of result.name if I did not have the namespace alias. I guess my question is, am I doing this the right way?

I've read that "If an element has a namespace alias, the alias and element are concatenated using "$". For example, ns:element becomes ns$element" If I do this I can read the attribute as result.d$name. If I went this route, how would I got about doing so?

I am trying to convert XML to JSON in node.js using the module xml2js. How do I handle the namespace alias when accessing variables?

The follow code converts my file (sampleWithNamespaces.xml)

var fs = require('fs'),
xml2js = require('xml2js');

var parser = new xml2js.Parser();
fs.readFile('sampleWithNamespaces.xml', function (err, data) {
    parser.parseString(data, function (err, result) {
        console.dir(result);
        console.log('Done');
    });
});

sampleWithNamespaces.xml :

<d:student xmlns:d='http://www.develop.com/student'>
  <d:id>3235329</d:id>
  <d:name>Jeff Smith</d:name>
  <d:language>JavaScript</d:language>
  <d:rating>9.5</d:rating>
</d:student>

Output:

$ node xml2jsTest.js
{ '@': { 'xmlns:d': 'http://www.develop.com/student' },
  'd:id': '3235329',
  'd:name': 'Jeff Smith',
  'd:language': 'JavaScript',
  'd:rating': '9.5' }
Done

I can access the 'name' attribute by using the notation result['d:name'] instead of result.name if I did not have the namespace alias. I guess my question is, am I doing this the right way?

I've read that "If an element has a namespace alias, the alias and element are concatenated using "$". For example, ns:element becomes ns$element" If I do this I can read the attribute as result.d$name. If I went this route, how would I got about doing so?

Share Improve this question asked Jun 29, 2012 at 16:56 Travis NelsonTravis Nelson 2,6205 gold badges29 silver badges34 bronze badges
Add a comment  | 

4 Answers 4

Reset to default 8

I had a similar issue. Most of my XML tags were in a single namespace. So i decided to strip out all the namespaces from my XML.

It is possible to strip out namespaces while parsing XML by adding a tagNameProcessors to xml2js.

var parseString = require('xml2js').parseString;
var stripNS = require('xml2js').processors.stripPrefix;

parseString(xml_str, { tagNameProcessors: [stripNS] },function(err, result) {});

This will technically ignore all the namespace. If you have XML tags from multiple namespaces, then this might not be of great use.

For those who use typescript

  • add this import statement (you will need npm install -D @types/xml2js)
import { Parser, processors } from 'xml2js';
  • add tagNameProcessor option when create a new parser
    const parser = new Parser(
        {  
            trim: true,  
            explicitArray: false,
            tagNameProcessors: [processors.stripPrefix]
        });
        parser.parseString(xmlData, function(err, result)
        { 

if you use node and xml2js use result["ns:entry"] to refer to a specific entry

The document you quote has nothing to do with xml2js, but you can get the same pattern if you want. You'd have to change the source code of xml2js or loop through renaming everything after loading it, both of which are not great ideas (the first means you won't be able to update so easily, and both add overhead to your code), so you should probably just stick to the ['d:name'] syntax. The only disadvantage is that it adds 3 characters to each lookup, but if your server uses gzip it won't make a difference in the real world.

If you really want to, this function will rename everything:

function colonToDollar(obj){
    var r={};
    for(var k in obj){
        r[k.replace(/:/g,'$')] = (typeof obj[k]==='object') ? colonToDollar(obj[k]) : obj[k];
    }
    return r;
}
发布评论

评论列表(0)

  1. 暂无评论