【问题标题】:Node.js - Help Converting XML to Custom JSONNode.js - 帮助将 XML 转换为自定义 JSON
【发布时间】:2014-07-18 04:16:09
【问题描述】:

我正在构建一个 xml 到 json 函数,它将我们的 XML 结构转换为特定格式的 JSON。

我尝试了许多库,最终,我决定将 XML 转换为 DOM 树,我可以自己遍历并转换为 JSON,因为这些库不提供我需要的格式。

下面是一个示例 xml 文档:

var xml = '<document>' +
            '<divisions>' +
              '<division id="123" division="foo">' +
                '<departments>' +
                  '<department id="456" department="bar"/>'+
                  '<department id="678" department="bar"/>'+
                '</departments>' +
              '</division>' +
            '</divisions>' +

            '<roles>' +
              '<role id="123" name="foo"/>' +
              '<role id="123" name="foo"/>' +
            '</roles>' +
          '</document>';

期望的输出:

{ divisions: [ { id: '123', division: 'foo', departments: [ { id: '456', department: 'bar' } ] } ], roles: [ { id: '123', name: 'foo'}, { id: '123', name: 'foo'} ] }

这是我最初的尝试:

var DOMParser = require('xmldom').DOMParser;

function XMLtoJSON(xml) {

  var json = {};
  var dom  = new DOMParser().parseFromString(xml).childNodes[0];

  function process(nodes, parent) {

    var node, name, hasChildren;

    for(var i = 0, l = nodes.length; i < l; i++) {

      node        = nodes[i];
      name        = node.tagName;
      hasChildren = node.hasChildNodes();

      if(!parent) {
        json[name] = [];
      }

      if(node.hasAttributes()) {

        var attributes = node.attributes, obj = {};
        for(var x = 0, al = attributes.length; x < al; x++) {

          obj[attributes[x].name] = attributes[x].value;

          if(!parent) {
            json[name].push(obj);
          }
        }
      }

      if(hasChildren) {
        process(nodes[i].childNodes);
      }
    }
  }

  process(dom.childNodes);

  return json;
}

console.log( XMLtoJSON(xml) );

目前,这将输出:

{ divisions: [],
  division: 
   [ { id: '123', division: 'foo' },
     { id: '123', division: 'foo' } ],
  departments: [],
  department: 
   [ { id: '678', department: 'bar' },
     { id: '678', department: 'bar' } ],
  roles: [],
  role: [ { id: '123', name: 'foo' }, { id: '123', name: 'foo' } ] }

注意:我不想在我的 json 中添加父 document,因此初始 parseFromString(xml).childNodes[0];

我想知道是否有人可以帮助我靠近一点。具体来说,我很难理解如何处理嵌入式集合(部门是部门内的一个数组)。我已经为此工作了几个小时,递归一直让我绊倒。

【问题讨论】:

  • 我没有看到任何使用parent 参数调用process 的地方,所以我很好奇它为什么要测试两次。

标签: javascript xml json node.js


【解决方案1】:

抱歉这么久才回复。这有点难。以下代码至少适用于您当前的示例 XML。棘手的部分是决定哪些元素是数组,哪些元素不是。这里的逻辑是所有有属性的都是对象,其他的都是数组。

function DOMToObject (node, obj, isArray) {

    var child = node.firstChild,
        attributes,
        newObj,
        i,
        j,
        k = 0;

    if (!obj) {
        obj = {};
    }

    while (child) {

        attributes = child.attributes;

        if (attributes && attributes.length) {

            newObj = {};
            DOMToObject(child, newObj);

            for (i = 0, j = attributes.length; i < j; i++) {
                newObj[attributes[i].name] = attributes[i].value;
            }

        } else {

            newObj = [];
            DOMToObject(child, newObj, true);
        }

        if (isArray) {
            obj[k] = newObj;
            k += 1;

        } else {
            obj[child.nodeName] = newObj;
        }

        child = child.nextSibling;
    }

    return obj;
};

var JSON = JSON.stringify(DOMToObject(dom.firstChild));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-19
    • 1970-01-01
    • 2014-07-23
    • 2021-11-06
    • 1970-01-01
    • 2018-04-14
    • 2012-05-16
    • 1970-01-01
    相关资源
    最近更新 更多