使用Javascript将JSON转换为XML

11

我正在尝试将JSON转换为XML,但没有得到精确的输出。我的JSON中有一个数组对象,它没有将其转换为XML数组。主要问题是数组对象没有按预期转换为XML。

var InputJSON = "{"body":{"entry": [{ "fullURL" : "abcd","Resource": "1234"},{ "fullURL" : "efgh","Resource": "5678"}]}}";
var output = eval("OBJtoXML("+InputJSON+");")

function OBJtoXML(obj) {
    var xml = '';
    for (var prop in obj) {
        xml += "<" + prop + ">";
        if(obj[prop] instanceof Array) {
            for (var array in obj[prop]) {
                xml += OBJtoXML(new Object(obj[prop][array]));
            }
        } else if (typeof obj[prop] == "object") {
            xml += OBJtoXML(new Object(obj[prop]));
        } else {
            xml += obj[prop];
        }
        xml += "</" + prop + ">";
    }
    var xml = xml.replace(/<\/?[0-9]{1,}>/g,'');
    return xml
}
<body>
  <entry>
    <fullURL>abcd</fullURL>
    <Resource>1234</Resource>
    <fullURL>efgh</fullURL>
    <Resource>5678</Resource>
  </entry>
</body>

预期输出:

<body>
  <entry>
    <fullURL>abcd</fullURL>
    <Resource>1234</Resource>
  </entry>
 <entry>
    <fullURL>efgh</fullURL>
    <Resource>5678</Resource>
  </entry>
</body>

如果我的代码中有遗漏的地方,请指导我如何得到期望的结果。


请看这里:https://dev59.com/P3I-5IYBdhLWcg3wm5lG - scagood
var InputJSON = "{"body":{"entry": [{ "fullURL" : "abcd","Resource": "1234"},{ "fullURL" : "efgh","Resource": "5678"}]}}" 不是有效的 JSON。 - Usman Wali
谢谢您的及时回复,Usman。但是我已经检查了JSON,它是有效的,而且我需要在没有任何解析器和序列化程序的情况下进行转换。 - nkn
8个回答

16

请将您的OBJtoXML函数替换为

function OBJtoXML(obj) {
  var xml = '';
  for (var prop in obj) {
    xml += obj[prop] instanceof Array ? '' : "<" + prop + ">";
    if (obj[prop] instanceof Array) {
      for (var array in obj[prop]) {
        xml += "<" + prop + ">";
        xml += OBJtoXML(new Object(obj[prop][array]));
        xml += "</" + prop + ">";
      }
    } else if (typeof obj[prop] == "object") {
      xml += OBJtoXML(new Object(obj[prop]));
    } else {
      xml += obj[prop];
    }
    xml += obj[prop] instanceof Array ? '' : "</" + prop + ">";
  }
  var xml = xml.replace(/<\/?[0-9]{1,}>/g, '');
  return xml
}

1
太棒了,Usman,它按预期工作了...感谢您的及时回复.. :) - nkn
如果属性或属性包含斜杠,则此方法无效。例如,JSON 属性 "team/stats" 将无法正常工作,因为它将被转换为无效的 XML <team/stats>。 - Tom McDonald
无法使用 & 符号,必须将其转换为 &,否则会阻止 XML 处理。 - Jan

4

3

这里存在一些问题。首先,JSON字符串变量需要转义引号或用单引号括起来。例如:

var InputJSON = '{"body":{"entry": [{ "fullURL" : "abcd","Resource": "1234"},{ "fullURL" : "efgh","Resource": "5678"}]}}';

接下来,在JavaScript中使用JSON时,无需使用eval,应使用JSON.parse

// First parse the JSON
var InputJSON = JSON.parse(InputJSON);

// Now execute the 'OBJtoXML' function
var output = OBJtoXML(InputJSON);

现在我们来到这个问题的核心,为什么entry只出现一次? 你遇到的问题是xml += "<" + prop + ">";xml += "</" + prop + ">";每个属性只发生一次。 一个可能的解决方案如下:
function OBJtoXML(obj) {
    var xml = '';
    for (var prop in obj) {
        xml += "<" + prop + ">";
        if(Array.isArray(obj[prop])) {
            for (var array of obj[prop]) {

                // A real botch fix here
                xml += "</" + prop + ">";
                xml += "<" + prop + ">";

                xml += OBJtoXML(new Object(array));
            }
        } else if (typeof obj[prop] == "object") {
            xml += OBJtoXML(new Object(obj[prop]));
        } else {
            xml += obj[prop];
        }
        xml += "</" + prop + ">";
    }
    var xml = xml.replace(/<\/?[0-9]{1,}>/g,'');
    return xml
}

2

Xml-to-json 库中有 jsonToXml(json)xmlToJson(xml) 两个方法。

https://xmltojson.github.io

var inputJSON = '{"body":{"entry": [{ "fullURL" : "abcd","Resource": "1234"},{ "fullURL" : "efgh","Resource": "5678"}]}}';

var xml = jsonToXml(inputJSON);

// <?xml version="1.0" encoding="UTF-8"?>
// <body>
//   <entry>
//     <fullURL>abcd</fullURL>
//     <Resource>1234</Resource>
//   </entry>
//   <entry>
//     <fullURL>efgh</fullURL>
//     <Resource>5678</Resource>
//   </entry>
// </body>

https://www.utilities-online.info/xmltojson 使用了这个库。 - Valentyn Kolesnikov

1
var inputJSON = '{"body":{"entry": [{ "fullURL" : "abcd","Resource": "1234"},{ "fullURL" : "efgh","Resource": "5678"}]}}';
var parsedInput = JSON.parse(inputJSON);

function OBJtoXML(obj) {
    var xml = '';
    for (var prop in obj) {
        if (obj[prop] instanceof Array) {
            for (var array in obj[prop]) {
                xml += '<' + prop + '>';
                xml += OBJtoXML(new Object(obj[prop][array]));
                xml += '</' + prop + '>';
            }
        } else {
            xml += '<' + prop + '>';
            typeof obj[prop] == 'object' ? xml += OBJtoXML(new Object(obj[prop])) : xml += obj[prop];
            xml += '</' + prop + '>';
        }
    }
    var xml = xml.replace(/<\/?[0-9]{1,}>/g, '');
    return xml;
}

感谢@Anderi Ros提供的解决方案。在这里,我尝试不使用任何内置库来解析JSON。所以我使用了"eval"。 - nkn

0

对象/数组转XML转换器

以下解决方案可以将JS变量转换为(非缩进)XML字符串。它支持列表(数组)和对象。

  • 使用objectToXml(object)创建一个带有单个根元素的有效XML。
  • 如果要转换元素数组,请使用variableToXml(variable, 'listElementName')。在这种情况下,您必须将列表元素的标记名称作为第二个参数传递。
function objectToXml(object) {
  if (object instanceof Array || Object.keys(object).length !== 1) {
    throw 'variable has to be an object with a single property'
  }
  return variableToXml(object)
}

function variableToXml(variable, arrayItemPropertyName = null) {
  if (Array.isArray(variable)) {
    return variable.reduce((xml, propertyValue) => {
      const value = variableToXml(propertyValue)
      return `${xml}<${arrayItemPropertyName}>${value}</${arrayItemPropertyName}>`
    }, '')
  }
  if (variable instanceof Object) {
    return Object.entries(variable).reduce((xml, [propertyName, propertyValue]) => {
      const value = variableToXml(propertyValue, propertyName )
      const tag = propertyValue instanceof Array ? value : `<${propertyName}>${value}</${propertyName}>`
      return `${xml}${tag}`
    }, '')
  }
  return variable
}

输入变量

const object = {
  rootTag: {
    intProperty: 4,
    stringProperty: 'foo',
    listOfElements: {
      element: [{
        intProperty: 5,
        stringProperty: 'bar',
      }, {
        intProperty: 5,
        stringProperty: 'bar',
      }],
    },
    list: {
      listElement: [1, 2, 3],
    },
  },
}

输出格式化的 XML

<rootTag>
  <intProperty>4</intProperty>
  <stringProperty>foo</stringProperty>
  <listOfElements>
    <element>
      <intProperty>5</intProperty>
      <stringProperty>bar</stringProperty>
    </element>
    <element>
      <intProperty>5</intProperty>
      <stringProperty>bar</stringProperty>
    </element>
  </listOfElements>
  <list>
    <listElement>1</listElement>
    <listElement>2</listElement>
    <listElement>3</listElement>
  </list>
</rootTag>

演示

const object = {
  rootTag: {
    intProperty: 4,
    stringProperty: 'foo',
    listOfElements: {
      element: [{
        intProperty: 5,
        stringProperty: 'bar',
      }, {
        intProperty: 5,
        stringProperty: 'bar',
      }],
    },
    list: {
      listElement: [1, 2, 3],
    },
  },
}

console.log(objectToXml(object))

function objectToXml(object) {
  if (object instanceof Array || Object.keys(object).length !== 1) {
    throw 'variable has to be an object with a single property'
  }
  return variableToXml(object)
}

function variableToXml(variable, arrayItemPropertyName = null) {
  if (Array.isArray(variable)) {
    return variable.reduce((xml, propertyValue) => {
      const value = variableToXml(propertyValue)
      return `${xml}<${arrayItemPropertyName}>${value}</${arrayItemPropertyName}>`
    }, '')
  }
  if (variable instanceof Object) {
    return Object.entries(variable).reduce((xml, [propertyName, propertyValue]) => {
      const value = variableToXml(propertyValue, propertyName )
      const tag = propertyValue instanceof Array ? value : `<${propertyName}>${value}</${propertyName}>`
      return `${xml}${tag}`
    }, '')
  }
  return variable
}


0
function OBJtoXML(obj, index) {
    var xml = '', 
        root, 
        count = 0;
    if (index > 0) count = index;
    for (var prop in obj) {
      switch (typeof obj[prop]) {
          case 'object': {
              if(obj[prop] instanceof Array) {
                  for (var instance in obj[prop]) {
                    xml += `\n\t<${prop}>\n${OBJtoXML(new Object(obj[prop][instance]))}\t</${prop}>`;
                  }
              }
              else {
                  if (count === 0) {
                    // console.log(`Setting root: ${prop}`)
                    root = prop
                  }
                  xml += `<${prop}>${OBJtoXML(new Object(obj[prop]), count)}\n</${prop}>\n`;
              }
              break;
          }
          case 'number':
          case 'string': {
              // console.log(`Setting ${typeof obj[prop]}`)
              xml += `\t\t<${prop}>${obj[prop]}</${prop}>\n`;
              break;
          }
      }
      count += 1;
    }
    return xml
}

var InputJSON = '{"body":{"entry": [{ "fullURL" : "abcd","Resource": "1234"},{ "fullURL" : "efgh","Resource": "5678"}]}}';
var output = eval("OBJtoXML("+InputJSON+");");
console.log(output);

0
const objectToXml = (object) => Object.keys(object).reduce((reqStr, key) => {
  const value = object[key] || '';
  const isObject = typeof value === 'object';
  const isArray = Array.isArray(value);
  if (isArray) {
    return reqStr + value.reduce((accumulator, currentValue) =>
      accumulator + `<${key}>${ typeof currentValue === 'object' ? objectToXml(currentValue) : (currentValue || '')}</${key}>`
    ,'');
  }
  if (isObject) {
    return reqStr + `<${key}>${objectToXml(value)}</${key}>`;
  }
  return reqStr + `<${key}>${value}</${key}>`;
}, '');       

const output = objectToXml(yourJson);
console.log(output);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接