Convierta XML a JSON (y viceversa) usando Javascript

Resuelto Jason Suárez asked hace 15 años • 14 respuestas

¿Cómo convertirías de XML a JSON y luego volverías a XML?

Las siguientes herramientas funcionan bastante bien, pero no son completamente consistentes:

  • xml2json

¿Alguien se ha encontrado con esta situación antes?

Jason Suárez avatar Nov 21 '09 05:11 Jason Suárez
Aceptado

Creo que este es el mejor: Convertir entre XML y JSON

Asegúrese de leer el artículo adjunto en el sitio xml.com de O'Reilly , que detalla los problemas con estas conversiones, lo cual creo que le resultará esclarecedor. El hecho de que O'Reilly sea el anfitrión del artículo debería indicar que la solución de Stefan tiene mérito.

Josh Stodola avatar Nov 20 '2009 22:11 Josh Stodola

https://github.com/abdmob/x2js : mi propia biblioteca (URL actualizada desde http://code.google.com/p/x2js/ ):

Esta biblioteca proporciona funciones de conversión de XML a JSON (objetos JavaScript) y viceversa. La biblioteca es muy pequeña y no requiere otras bibliotecas adicionales.

Funciones API

  • new X2JS(): para crear su instancia y acceder a todas las funciones de la biblioteca. También puede especificar opciones de configuración opcionales aquí
  • X2JS.xml2json: convierte XML especificado como objeto DOM a JSON
  • X2JS.json2xml - Convertir JSON a objeto DOM XML
  • X2JS.xml_str2json: convierte XML especificado como cadena a JSON
  • X2JS.json2xml_str - Convertir JSON a cadena XML

Demostración en línea en http://jsfiddle.net/abdmob/gkxucxrj/1/

var x2js = new X2JS();
function convertXml2JSon() {
    $("#jsonArea").val(JSON.stringify(x2js.xml_str2json($("#xmlArea").val())));
}

function convertJSon2XML() {
    $("#xmlArea").val(x2js.json2xml_str($.parseJSON($("#jsonArea").val())));
}

convertXml2JSon();
convertJSon2XML();
$("#convertToJsonBtn").click(convertXml2JSon);
$("#convertToXmlBtn").click(convertJSon2XML);
abdolence avatar Dec 09 '2011 13:12 abdolence

Estas respuestas me ayudaron mucho a hacer esta función:

function xml2json(xml) {
  try {
    var obj = {};
    if (xml.children.length > 0) {
      for (var i = 0; i < xml.children.length; i++) {
        var item = xml.children.item(i);
        var nodeName = item.nodeName;

        if (typeof (obj[nodeName]) == "undefined") {
          obj[nodeName] = xml2json(item);
        } else {
          if (typeof (obj[nodeName].push) == "undefined") {
            var old = obj[nodeName];

            obj[nodeName] = [];
            obj[nodeName].push(old);
          }
          obj[nodeName].push(xml2json(item));
        }
      }
    } else {
      obj = xml.textContent;
    }
    return obj;
  } catch (e) {
      console.log(e.message);
  }
}

Siempre que pases un objeto jquery dom/xml: para mí fue:

Jquery(this).find('content').eq(0)[0]

donde contenido era el campo en el que estaba almacenando mi xml.

Ryan Conrad avatar Dec 31 '2013 18:12 Ryan Conrad

Creé una función recursiva basada en expresiones regulares, en caso de que no desees instalar la biblioteca y comprender la lógica detrás de lo que está sucediendo:

const xmlSample = '<tag>tag content</tag><tag2>another content</tag2><tag3><insideTag>inside content</insideTag><emptyTag /></tag3>';
console.log(parseXmlToJson(xmlSample));

function parseXmlToJson(xml) {
    const json = {};
    for (const res of xml.matchAll(/(?:<(\w*)(?:\s[^>]*)*>)((?:(?!<\1).)*)(?:<\/\1>)|<(\w*)(?:\s*)*\/>/gm)) {
        const key = res[1] || res[3];
        const value = res[2] && parseXmlToJson(res[2]);
        json[key] = ((value && Object.keys(value).length) ? value : res[2]) || null;

    }
    return json;
}
Expandir fragmento

Explicación de expresiones regulares para cada bucle:

  • res[0] - devuelve el xml (tal cual)
  • res[1] - devuelve el nombre de la etiqueta xml
  • res[2] - devuelve el contenido xml
  • res[3] - devuelve el nombre de la etiqueta xml en caso de que la etiqueta se cierre sola. Por ejemplo:<tag />

Puedes comprobar cómo funciona la expresión regular aquí: https://regex101.com/r/ZJpCAL/1

Nota: En caso de que json tenga una clave con un valor indefinido, se eliminará. Por eso inserté null al final de la línea 9.

MasterPiece avatar May 04 '2020 13:05 MasterPiece

Estaba usando xmlToJson solo para obtener un valor único del xml.
Descubrí que hacer lo siguiente es mucho más fácil (si el xml solo aparece una vez...)

let xml =
'<person>' +
  ' <id>762384324</id>' +
  ' <firstname>Hank</firstname> ' +
  ' <lastname>Stone</lastname>' +
'</person>';

let getXmlValue = function(str, key) {
  return str.substring(
    str.lastIndexOf('<' + key + '>') + ('<' + key + '>').length,
    str.lastIndexOf('</' + key + '>')
  );
}


alert(getXmlValue(xml, 'firstname')); // gives back Hank
Expandir fragmento

Nebulosar avatar Jun 21 '2019 10:06 Nebulosar