Convierte XML a JSON (y viceversa) usando Javascript

145

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

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

¿Alguien ha encontrado esta situación antes?

Jason Suárez
fuente
8
Explique las inconsistencias, por favor
Josh Stodola
44
Específicamente, tenía que ver con la conversión de matrices JSON con solo 1 elemento a XML. Cuando lo convirtió de nuevo a JSON, en lugar de una matriz de 1 elemento, creó el objeto literal. Lo solucioné comprobando el tipo con $ .isArray () y envolviéndolo en una matriz si! $. IsArray ().
Jason Suárez el
1
xml2json - fyneworks.com/jquery/xml-to-json - rompe lanzamientos 500 a partir del 15/02/2013 14:25 AEST
ysrb
El enlace json2xml está roto.
whirlwin
@ysrb ¡El ejemplo del complemento no funcionará en IE8!
amigo

Respuestas:

103

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

Asegúrese de leer el artículo adjunto en el sitio de xml.com O'Reilly , que detalla los problemas con estas conversiones, que creo que encontrará esclarecedores. 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
fuente
¡gracias por la respuesta! En mi caso, el JSON es la representación canónica, y XML solo se usa para XSLT ... ¡cuyo uso no es idea mía! :)
Jason Suárez el
Esto es solo en el navegador. No se aplica para node.js o entornos que no sean del navegador. ¿Alguna otra idea?
Homer6
1
En lo que respecta al comentario de @JasonDenizac a su publicación, no estoy seguro de entender cómo este enlace ayuda a solucionar el problema de tener un objeto en lugar de una matriz de un elemento ...
guiomie
1
Descubrí que si comienzas desde json-xml-json, esta biblioteca funciona bien, pero si quieres xml-json-xml hay un problema con la reversibilidad ya que agrega elementos de metadatos xml como <o> y <e>
vishr
3
Tenga en cuenta que esta es una solución con licencia copyleft. Es solo una opción cuando está escribiendo software de código abierto.
Jasper
48

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

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

Funciones API

  • nuevo X2JS (): para crear su instancia para 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 - Convierte JSON a una 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);
abdolencia
fuente
1
Hola, ¿cómo superaste el problema de que si tienes un objeto en un objeto está en el objeto literal, donde si hay n> 1 objetos, tienes una matriz? Esto hace que sea difícil usar objetos xml a json en las plantillas ...
guiomie
Sí, debe usar algún truco y depende de su conocimiento sobre la estructura XML (porque no hay XSD aquí). Utilice <nodo> ... <nodo> _asSintaxis de matriz para acceder a su nodo siempre como matriz (secuencia)
abdolencia
1
Ejemplo: // cadena XML a JSON var xmlText = "<MyOperation> <test> Success </test> <test2> <item> ddsfg </item> <item> dsdgfdgfd </item> </test2> </MyOperation> "; var jsonObj = X2JS.xml_str2json (xmlText); alerta (jsonObj.MyOperation.test); alerta (jsonObj.MyOperation.test_asArray [0]);
abdolencia
Mi principal problema es cuando transformo mi json a xml, el json está lleno de propiedades adicionales y cuando la versión de cadena xml mantiene todas las cosas inútiles. Tiene todo tipo de comas y espacios en blanco ...
guiomie
podría presentar su muestra a code.google.com/p/x2js/issues lo comprobaré
abdolence
25

Estas respuestas me ayudaron mucho para hacer que 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 pase un objeto jquery dom / xml: para mí fue:

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

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

Ryan Conrad
fuente
3

Hace un tiempo escribí esta herramienta https://bitbucket.org/surenrao/xml2json para mi aplicación TV Watchlist, espero que esto también ayude.

Sinopsis: una biblioteca para no solo convertir xml a json, sino que también es fácil de depurar (sin errores circulares) y recrear json nuevamente a xml. Características: - Analizar xml a objeto json. Imprima el objeto json de nuevo a xml. Se puede usar para guardar xml en IndexedDB como objetos X2J. Imprimir objeto json.

surya
fuente
@kleopatra este enlace apunta a la herramienta que convierte xml a json. No es una referencia, sino el enlace real al recurso. No estoy seguro de qué otra manera debería hacerlo :)
surya
2

Yo personalmente recomendaría esta herramienta . Es un convertidor de XML a JSON.

Es muy ligero y está en JavaScript puro. No necesita dependencias. Simplemente puede agregar las funciones a su código y usarlo como desee.

También toma los atributos XML en consideración.

var xml = ‘<person id=”1234 age=”30”><name>John Doe</name></person>’;
var json = xml2json(xml); 

console.log(json); 
// prints ‘{“person”: {“id”: “1234”, “age”: “30”, “name”: “John Doe”}}’

¡Aquí hay una demostración en línea !

Samuel Bourgault
fuente
44
repositorio de github no encontrado
brauliobo
1

Descargo de responsabilidad: he escrito fast-xml-parser

Fast XML Parser puede ayudar a convertir XML a JSON y viceversa. Aquí está el ejemplo;

var options = {
    attributeNamePrefix : "@_",
    attrNodeName: "attr", //default is 'false'
    textNodeName : "#text",
    ignoreAttributes : true,
    ignoreNameSpace : false,
    allowBooleanAttributes : false,
    parseNodeValue : true,
    parseAttributeValue : false,
    trimValues: true,
    decodeHTMLchar: false,
    cdataTagName: "__cdata", //default is 'false'
    cdataPositionChar: "\\c",
};
if(parser.validate(xmlData)=== true){//optional
    var jsonObj = parser.parse(xmlData,options);
}

Si desea analizar objetos JSON o JS en XML, entonces

//default options need not to set
var defaultOptions = {
    attributeNamePrefix : "@_",
    attrNodeName: "@", //default is false
    textNodeName : "#text",
    ignoreAttributes : true,
    encodeHTMLchar: false,
    cdataTagName: "__cdata", //default is false
    cdataPositionChar: "\\c",
    format: false, 
    indentBy: "  ",
    supressEmptyNode: false
};
var parser = new parser.j2xParser(defaultOptions);
var xml = parser.parse(json_or_js_obj);
Amit Kumar Gupta
fuente
: D FXP es más que un convertidor JSON XML 2. Por favor, compruebe que es léame.
Amit Kumar Gupta
1

Aquí hay una buena herramienta de una biblioteca npm documentada y muy famosa que realiza muy bien las conversiones xml <-> js: a diferencia de algunas (quizás todas) de las soluciones propuestas anteriormente, también convierte los comentarios xml.

var obj = {name: "Super", Surname: "Man", age: 23};

var builder = new xml2js.Builder();
var xml = builder.buildObject(obj);
SimoneMSR
fuente
1

En 6 líneas simples de ES6:

xml2json = xml => {                                                                                                                                                     
  var el = xml.nodeType === 9 ? xml.documentElement : xml                                                                                                               
  var h  = {name: el.nodeName}                                                                                                                                          
  h.content    = Array.from(el.childNodes || []).filter(e => e.nodeType === 3).map(e => e.textContent).join('').trim()                                                  
  h.attributes = Array.from(el.attributes || []).filter(a => a).reduce((h, a) => { h[a.name] = a.value; return h }, {})                                                 
  h.children   = Array.from(el.childNodes || []).filter(e => e.nodeType === 1).map(c => h[c.nodeName] = xml2json(c))                                                    
  return h                                                                                                                                                              
}  

Prueba con echo "xml2json_example()" | node -r xml2json.es6 fuente en https://github.com/brauliobo/biochemical-db/blob/master/lib/xml2json.es6

brauliobo
fuente
0

Estaba usando xmlToJson solo para obtener un valor único de xml.
Descubrí que hacer lo siguiente es mucho más fácil (si el xml solo ocurre 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

Nebulosar
fuente
0

He creado una función recursiva basada en expresiones regulares, en caso de que no desee 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;
}

Explicación de expresiones regulares para cada ciclo:

  • res [0] - devuelve el xml (como está)
  • 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 />

Puede verificar 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á. Es por eso que he insertado nulo al final de la línea 9.

Obra maestra
fuente
-2

La mejor manera de hacerlo usando el lado del servidor como cliente no funciona bien en todos los escenarios. Estaba tratando de construir un convertidor json a xml y xml a json en línea usando javascript y me sentí casi imposible ya que no funcionaba en todos los escenarios. Finalmente terminé haciéndolo en el lado del servidor usando Newtonsoft en ASP.MVC. Aquí está el convertidor en línea http://techfunda.com/Tools/XmlToJson

Sheo Narayan
fuente