Konwertuj XML na JSON (iz powrotem) za pomocą JavaScript

145

Jak przekonwertowałbyś XML na JSON, a następnie z powrotem na XML?

Następujące narzędzia działają całkiem dobrze, ale nie są całkowicie spójne:

Czy ktoś wcześniej spotkał się z tą sytuacją?

Jason Suárez
źródło
8
Proszę wyjaśnić niekonsekwencje
Josh Stodola,
4
W szczególności chodziło o konwersję tablic JSON z tylko jednym elementem do XML. Po przekonwertowaniu go z powrotem na JSON, zamiast tablicy 1-elementowej, utworzył literał obiektu. Obejrzałem to, sprawdzając typ za pomocą $ .isArray () i opakowując go w tablicę, jeśli! $. IsArray ().
Jason Suárez
1
xml2json - fyneworks.com/jquery/xml-to-json - przerwy rzuca 500 od 15/02/2013 14:25 AEST
ysrb
Link json2xml jest uszkodzony.
whirlwin
@ysrb Przykład wtyczki nie będzie działał w IE8!
koleś

Odpowiedzi:

103

Myślę, że to jest najlepsze: Konwersja między XML a JSON

Koniecznie przeczytaj towarzyszący artykuł w witrynie xml.com O'Reilly , w którym omawiamy szczegółowo problemy z tymi konwersjami, które, jak sądzę, uznasz za pouczające. Fakt, że O'Reilly prowadzi artykuł, powinien wskazywać, że rozwiązanie Stefana ma zalety.

Josh Stodola
źródło
Dziękuję za odpowiedź! W moim przypadku JSON jest reprezentacją kanoniczną, a XML jest po prostu używany do XSLT .. którego użycie nie jest moim pomysłem! :)
Jason Suárez
To jest tylko w przeglądarce. Nie dotyczy środowisk node.js lub innych niż przeglądarki. Jakieś inne pomysły?
Homer6
1
Jeśli chodzi o komentarz @JasonDenizac do jego posta, nie jestem pewien, czy rozumiem, w jaki sposób ten link pomaga rozwiązać problem posiadania obiektu zamiast tablicy jednego elementu ...
guiomie
1
Odkryłem, że jeśli zaczynasz od json-xml-json, ta biblioteka działa dobrze, ale jeśli chcesz xml-json-xml, jest problem z odwracalnością, ponieważ dodaje elementy xml metadanych, takie jak <o> i <e>
vishr
3
Należy pamiętać, że jest to rozwiązanie objęte licencją typu copyleft. Jest to opcja dostępna tylko w przypadku pisania oprogramowania typu open source.
Jasper
48

https://github.com/abdmob/x2js - moja własna biblioteka (zaktualizowany adres URL z http://code.google.com/p/x2js/ ):

Ta biblioteka dostarcza XML do JSON (JavaScript Objects) i odwrotnie do funkcji konwersji javascript. Biblioteka jest bardzo mała i nie wymaga żadnych innych dodatkowych bibliotek.

Funkcje API

  • nowe X2JS () - aby utworzyć instancję, aby uzyskać dostęp do wszystkich funkcji biblioteki. Możesz również określić tutaj opcjonalne opcje konfiguracji
  • X2JS.xml2json - Konwertuj XML określony jako obiekt DOM na JSON
  • X2JS.json2xml - Konwertuj JSON na obiekt XML DOM
  • X2JS.xml_str2json - Konwertuj XML określony jako ciąg na JSON
  • X2JS.json2xml_str - Konwertuj JSON na ciąg XML

Demo online na 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);
abdolencja
źródło
1
Cześć, w jaki sposób rozwiązałeś problem polegający na tym, że jeśli masz jeden obiekt w obiekcie, znajduje się on w literze obiektów, gdzie jeśli jest n> 1 obiektów, masz tablicę. To sprawia, że ​​trudno jest używać XML do obiektów json w szablonach ...
guiomie
Tak, powinieneś użyć jakiejś sztuczki i zależy to od twojej wiedzy o strukturze XML (ponieważ nie ma tutaj XSD). Użyj <node> ... <node> _asArray składnia dostępu do węzła zawsze jak array (sekwencji)
abdolence
1
Przykład: // ciąg XML do JSON var xmlText = "<MyOperation> <test> Sukces </test> <test2> <item> ddsfg </item> <item> dsdgfdgfd </item> </test2> </MyOperation> "; var jsonObj = X2JS.xml_str2json (xmlText); alert (jsonObj.MyOperation.test); alert (jsonObj.MyOperation.test_asArray [0]);
abdolence,
Moim głównym problemem jest to, że kiedy przekształcam mój json do xml z powrotem, json jest pełen dodatkowych właściwości, a kiedy wersja xml stringów zachowuje wszystkie bezużyteczne rzeczy. Zawiera wszelkiego rodzaju przecinki i spacje ...
guiomie
czy mógłbyś przesłać swoją próbkę na code.google.com/p/x2js/issues Sprawdzę to
abdolence,
25

Te odpowiedzi bardzo mi pomogły w wykonaniu tej funkcji:

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);
  }
}

Tak długo, jak przekazujesz obiekt jquery dom / xml: dla mnie było to:

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

gdzie zawartość była polem, w którym przechowywałem mój plik xml.

Ryan Conrad
źródło
3

Jakiś czas temu napisałem to narzędzie https://bitbucket.org/surenrao/xml2json dla mojej aplikacji TV Watchlist, mam nadzieję, że to też pomoże.

Streszczenie: Biblioteka, która nie tylko konwertuje xml na json, ale jest również łatwa do debugowania (bez błędów cyklicznych) i ponownie tworzy json z powrotem do xml. Cechy: - Parse XML do obiektu JSON. Drukuj obiekt JSON z powrotem do XML. Może służyć do zapisywania XML w IndexedDB jako obiektów X2J. Drukuj obiekt JSON.

surya
źródło
@kleopatra to łącze wskazuje na narzędzie, które konwertuje xml na json. To nie jest odniesienie, ale rzeczywisty link do zasobu. Nie wiem, jak inaczej powinienem to zrobić :)
surya
2

Osobiście poleciłbym to narzędzie . Jest to konwerter XML na JSON.

Jest bardzo lekki i jest w czystym JavaScript. Nie potrzebuje żadnych zależności. Możesz po prostu dodać funkcje do swojego kodu i używać go tak, jak chcesz.

Uwzględnia również atrybuty XML.

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”}}’

Oto demo online !

Samuel Bourgault
źródło
4
Nie znaleziono repozytorium github
brauliobo
1

Zastrzeżenie: napisałem parser fast-xml

Fast XML Parser może pomóc w konwersji XML do JSON i odwrotnie. Oto przykład;

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);
}

Jeśli chcesz przeanalizować obiekt JSON lub JS w XML, to

//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
źródło
: D FXP to coś więcej niż konwerter XML 2 JSON. Sprawdź, czy to plik readme.
Amit Kumar Gupta
1

Oto dobre narzędzie z udokumentowanej i bardzo znanej biblioteki npm, która bardzo dobrze wykonuje konwersje xml <-> js: inaczej niż niektóre (być może wszystkie) z powyższych proponowanych rozwiązań, konwertuje również komentarze xml.

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

var builder = new xml2js.Builder();
var xml = builder.buildObject(obj);
SimoneMSR
źródło
1

W 6 prostych liniach 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                                                                                                                                                              
}  

Przetestuj ze echo "xml2json_example()" | node -r xml2json.es6źródłem na https://github.com/brauliobo/biochemical-db/blob/master/lib/xml2json.es6

brauliobo
źródło
0

Użyłem xmlToJson tylko po to, aby uzyskać pojedynczą wartość XML.
Zauważyłem, że wykonanie następujących czynności jest znacznie łatwiejsze (jeśli plik XML występuje tylko raz ...)

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
źródło
0

Stworzyłem funkcję rekurencyjną opartą na wyrażeniu regularnym, na wypadek gdybyś nie chciał instalować biblioteki i rozumieć logiki stojącej za tym, co się dzieje:

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;
}

Wyjaśnienie wyrażenia regularnego dla każdej pętli:

  • res [0] - zwraca xml (tak jak jest)
  • res [1] - zwraca nazwę znacznika xml
  • res [2] - zwraca zawartość xml
  • res [3] - zwraca nazwę tagu xml w przypadku, gdy tag się zamyka. W przykładzie:<tag />

Sposób działania wyrażenia regularnego możesz sprawdzić tutaj: https://regex101.com/r/ZJpCAL/1

Uwaga: jeśli json ma klucz z nieokreśloną wartością, jest on usuwany. Dlatego wstawiłem null na końcu wiersza 9.

Arcydzieło
źródło
-2

Najlepszy sposób na zrobienie tego przy użyciu strony serwera jako strony klienta nie działa dobrze we wszystkich scenariuszach. Próbowałem zbudować online konwerter json na xml i xml na json przy użyciu javascript i czułem się prawie niemożliwy, ponieważ nie działał we wszystkich scenariuszach. Ostatecznie zrobiłem to po stronie serwera przy użyciu Newtonsoft w ASP.MVC. Oto konwerter online http://techfunda.com/Tools/XmlToJson

Sheo Narayan
źródło