Penguraian XML dari string variabel dalam JavaScript

204

Saya memiliki string variabel yang berisi XML yang dibentuk dengan baik dan valid. Saya perlu menggunakan kode JavaScript untuk mem-parsing umpan ini.

Bagaimana saya bisa mencapai ini menggunakan kode JavaScript (kompatibel dengan browser)?

David Bonnici
sumber

Jawaban:

90

Pembaruan: Untuk jawaban yang lebih benar lihat jawaban Tim Down .

Internet Explorer dan, misalnya, browser berbasis Mozilla mengekspos objek yang berbeda untuk parsing XML, jadi sebaiknya menggunakan kerangka kerja JavaScript seperti jQuery untuk menangani perbedaan lintas browser.

Contoh yang sangat mendasar adalah:

var xml = "<music><album>Beethoven</album></music>";

var result = $(xml).find("album").text();

Catatan: Seperti yang ditunjukkan dalam komentar; jQuery tidak benar-benar melakukan parsing XML apa pun, itu bergantung pada metode DOM innerHTML dan akan menguraikannya seperti halnya HTML apa pun jadi berhati-hatilah saat menggunakan nama elemen HTML di XML Anda. Tapi saya pikir itu bekerja cukup baik untuk 'parsing' XML sederhana, tetapi mungkin tidak disarankan untuk parsing XML intensif atau 'dinamis' di mana Anda tidak memunculkan XML apa yang akan turun dan ini menguji apakah semuanya mem-parsing seperti yang diharapkan.

Sander Versluys
sumber
6
Kode untuk mengabstraksi perbedaan parsing XML antara IE dan browser lain adalah beberapa baris sepele, jadi tidak ada gunanya lari pada 50K jQuery untuk sendiri. Memanipulasi DOM XML yang dihasilkan adalah masalah lain.
Tim Down
7
Dan sesuatu yang saya tidak sadari pada saat memposting komentar saya sebelumnya adalah bahwa jQuery bahkan tidak mem-parsing XML, itu hanya menetapkannya sebagai innerHTMLproperti elemen, yang sama sekali tidak dapat diandalkan.
Tim Down
Perhatikan bahwa JQuery tidak mendukung ruang nama XML. Lihat zachleat.com/web/2008/05/10/selecting-xml-with-javascript
mikemaccana
10
Jawaban ini salah. Lihat stackoverflow.com/questions/2124924/… , stackoverflow.com/questions/2908899/… , jawaban @Tim Down dan dokumentasi jQuery sendiri yang menyatakan: "Perhatikan bahwa [ jQuery()] mem-parsing HTML, bukan XML"
Crescent Fresh
2
@SanderVersluys: karena penulis tidak menerima jawaban lain, saya akan menyertakan catatan dalam jawaban Anda yang menghubungkan ke jawaban yang benar @ TimDown . Dengan begitu orang tidak perlu membaca semua komentar ini untuk mencari tahu jawaban yang benar.
Senseful
321

Jawaban yang diperbarui untuk 2017

Berikut ini akan menguraikan string XML ke dalam dokumen XML di semua browser utama. Kecuali jika Anda memerlukan dukungan untuk IE <= 8 atau browser yang tidak jelas, Anda dapat menggunakan fungsi berikut:

function parseXml(xmlStr) {
   return new window.DOMParser().parseFromString(xmlStr, "text/xml");
}

Jika Anda perlu mendukung IE <= 8, yang berikut ini akan melakukan pekerjaan:

var parseXml;

if (typeof window.DOMParser != "undefined") {
    parseXml = function(xmlStr) {
        return new window.DOMParser().parseFromString(xmlStr, "text/xml");
    };
} else if (typeof window.ActiveXObject != "undefined" &&
       new window.ActiveXObject("Microsoft.XMLDOM")) {
    parseXml = function(xmlStr) {
        var xmlDoc = new window.ActiveXObject("Microsoft.XMLDOM");
        xmlDoc.async = "false";
        xmlDoc.loadXML(xmlStr);
        return xmlDoc;
    };
} else {
    throw new Error("No XML parser found");
}

Setelah Anda Documentmemperoleh melalui parseXml, Anda dapat menggunakan metode / properti traversal DOM biasa seperti childNodesdan getElementsByTagName()untuk mendapatkan node yang Anda inginkan.

Contoh penggunaan:

var xml = parseXml("<foo>Stuff</foo>");
alert(xml.documentElement.nodeName);

Jika Anda menggunakan jQuery, dari versi 1.5 Anda dapat menggunakan parseXML()metode bawaannya, yang secara fungsional identik dengan fungsi di atas.

var xml = $.parseXML("<foo>Stuff</foo>");
alert(xml.documentElement.nodeName);
Tim Down
sumber
56
Saya setuju, jawaban ini harus diterima. Jawaban saya sudah sangat tua dari hari-hari awal, saya selalu merasa ingin tahu masih mendapat upvotes. Adakah yang mendukung untuk menghapus jawaban saya yang diterima? Dan apakah sistem pemungutan suara cacat? Suara positif orang-orang ini!
Sander Versluys
@SanderVersluys: Apakah Anda dapat menghapus jawaban Anda?
Witman
1
Harus menurunkan pendapat Anda karena mengatakan bahwa 'tidak ada jawaban yang layak lainnya'. Jawaban @SanderVersluys bekerja dengan baik dalam kasus saya. Apa yang tidak layak tentang itu, saya tidak tahu.
eric
2
@ EricTurner: Saya mendukungnya dan Sander sendiri telah menolak jawabannya. Dokumen jQuery memberi tahu Anda untuk tidak menggunakan $()parsing XML . Baca komentar lebih hati-hati: itu tidak bekerja dalam banyak situasi.
Tim Down
1
@DWoldrich: Saya sudah melihat keduanya di web, dan saya curiga ini bekerja dengan dua arah. Jawaban terdekat yang dapat saya temukan untuk jawaban otoritatif adalah msdn.microsoft.com/en-us/library/ms761398(v=vs.85).aspx , yang mengatakan bahwa Boolean harus digunakan. Namun, dan berapa banyak nilai yang Anda tempatkan sepenuhnya terserah Anda, metode jQueryparseXML() menggunakan string. Saya sedikit khawatir mengubah jawaban karena saya tidak punya cara mudah untuk mengujinya sekarang.
Tim Down
19

Sebagian besar contoh di web (dan beberapa yang disajikan di atas) menunjukkan cara memuat XML dari file dengan cara yang kompatibel dengan browser. Ini terbukti mudah, kecuali untuk Google Chrome yang tidak mendukung document.implementation.createDocument()metode ini. Saat menggunakan Chrome, untuk memuat file XML ke objek XmlDocument, Anda harus menggunakan objek XmlHttp inbuilt dan kemudian memuat file dengan meneruskannya URI.

Dalam kasus Anda, skenario berbeda, karena Anda ingin memuat XML dari variabel string , bukan URL. Namun untuk persyaratan ini, Chrome seharusnya berfungsi seperti Mozilla (atau yang saya dengar) dan mendukung metode parseFromString ().

Ini adalah fungsi yang saya gunakan (itu bagian dari perpustakaan kompatibilitas Browser yang saat ini saya bangun):

function LoadXMLString(xmlString)
{
  // ObjectExists checks if the passed parameter is not null.
  // isString (as the name suggests) checks if the type is a valid string.
  if (ObjectExists(xmlString) && isString(xmlString))
  {
    var xDoc;
    // The GetBrowserType function returns a 2-letter code representing
    // ...the type of browser.
    var bType = GetBrowserType();

    switch(bType)
    {
      case "ie":
        // This actually calls into a function that returns a DOMDocument 
        // on the basis of the MSXML version installed.
        // Simplified here for illustration.
        xDoc = new ActiveXObject("MSXML2.DOMDocument")
        xDoc.async = false;
        xDoc.loadXML(xmlString);
        break;
      default:
        var dp = new DOMParser();
        xDoc = dp.parseFromString(xmlString, "text/xml");
        break;
    }
    return xDoc;
  }
  else
    return null;
}
Cerebrus
sumber
16
Saya mengetahui pendapat kontroversial mengenai pernafasan Browser dan itulah alasan saya tidak memasukkan fungsi itu di sini. Namun, belum ditetapkan bahwa itu SALAH. Bagaimanapun, ini adalah contoh sugestif .
Cerebrus
1
Saya percaya itu salah karena Anda tidak dapat menjamin itu benar. Siapa pun dapat menipu string UA, dan diragukan bahwa SETIAP browser non-IE mendukung DOMParser, dan bahwa sniffing browser Anda SEMPURNA. Dan selain itu, jauh lebih mudah untuk melakukannya dengan cara yang benar:if(window.ActiveXObject){...}
1j01
Jadi sekarang IE9 + mendukung DOMParser , bagaimana Anda akan mendukungnya? -1 untuk apa yang dikatakan @jj01. Yang perlu Anda periksa adalah var dp; try{ dp = new DOMParser() } catch(e) { }; if(dp) { // DOMParser supported } else { // alert('you need to consider upgrading your browser\nOr pay extra money so developer can support the old versions using browser sniffing (eww)') }.
Annie
13

Marknote adalah parser JavaScript XML lintas-browser yang ringan dan bagus. Berorientasi objek dan punya banyak contoh, ditambah API yang didokumentasikan. Ini cukup baru, tetapi sejauh ini sudah bekerja dengan baik di salah satu proyek saya. Satu hal yang saya sukai dari itu adalah ia akan membaca XML langsung dari string atau URL dan Anda juga bisa menggunakannya untuk mengonversi XML menjadi JSON.

Berikut ini contoh yang dapat Anda lakukan dengan Marknote:

var str = '<books>' +
          '  <book title="A Tale of Two Cities"/>' +
          '  <book title="1984"/>' +
          '</books>';

var parser = new marknote.Parser();
var doc = parser.parse(str);

var bookEls = doc.getRootElement().getChildElements();

for (var i=0; i<bookEls.length; i++) {
    var bookEl = bookEls[i];
    // alerts "Element name is 'book' and book title is '...'"
    alert("Element name is '" + bookEl.getName() + 
        "' and book title is '" + 
        bookEl.getAttributeValue("title") + "'"
    );
}
Mike McMillien
sumber
Tampaknya marknote mengimplementasikan parser javascript murni. Itu berarti harus kompatibel dengan mesin javascript apa pun, di mana pun itu digunakan di browser, di node.js atau di mesin javascript mandiri ...
Coyote
8

Saya selalu menggunakan pendekatan di bawah ini yang berfungsi di IE dan Firefox.

XML Contoh:

<fruits>
  <fruit name="Apple" colour="Green" />
  <fruit name="Banana" colour="Yellow" />
</fruits>

JavaScript:

function getFruits(xml) {
  var fruits = xml.getElementsByTagName("fruits")[0];
  if (fruits) {
    var fruitsNodes = fruits.childNodes;
    if (fruitsNodes) {
      for (var i = 0; i < fruitsNodes.length; i++) {
        var name = fruitsNodes[i].getAttribute("name");
        var colour = fruitsNodes[i].getAttribute("colour");
        alert("Fruit " + name + " is coloured " + colour);
      }
    }
  }
}
John Topley
sumber
Bagaimana Anda mengambil nilai jika Anda memiliki situasi ini <fruit> nilai </fruit>?
Siblja
1
@ Siblja Anda perlu menggunakan innerTextbukangetAttribute()
Manux22
8

Rupanya jQuery sekarang menyediakan jQuery.parseXML http://api.jquery.com/jQuery.parseXML/ pada versi 1.5

jQuery.parseXML( data ) Pengembalian: XMLDocument

Jamie Pate
sumber
2

Silakan lihat XML DOM Parser ( W3Schools ). Ini adalah tutorial tentang parsing DOM XML. Parser DOM yang sebenarnya berbeda dari peramban ke peramban tetapi DOM API terstandarisasi dan tetap sama (lebih atau kurang).

Atau gunakan E4X jika Anda dapat membatasi diri untuk Firefox. Ini relatif lebih mudah digunakan dan merupakan bagian dari JavaScript sejak versi 1.6. Berikut adalah contoh penggunaan kecil ...

//Using E4X
var xmlDoc=new XML();
xmlDoc.load("note.xml");
document.write(xmlDoc.body); //Note: 'body' is actually a tag in note.xml,
//but it can be accessed as if it were a regular property of xmlDoc.
Otodidak
sumber
0
<script language="JavaScript">
function importXML()
{
    if (document.implementation && document.implementation.createDocument)
    {
            xmlDoc = document.implementation.createDocument("", "", null);
            xmlDoc.onload = createTable;
    }
    else if (window.ActiveXObject)
    {
            xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
            xmlDoc.onreadystatechange = function () {
                    if (xmlDoc.readyState == 4) createTable()
            };
    }
    else
    {
            alert('Your browser can\'t handle this script');
            return;
    }
    xmlDoc.load("emperors.xml");
}

function createTable()
{
    var theData="";
    var x = xmlDoc.getElementsByTagName('emperor');
    var newEl = document.createElement('TABLE');
    newEl.setAttribute('cellPadding',3);
    newEl.setAttribute('cellSpacing',0);
    newEl.setAttribute('border',1);
    var tmp = document.createElement('TBODY');
    newEl.appendChild(tmp);
    var row = document.createElement('TR');
    for (j=0;j<x[0].childNodes.length;j++)
    {
            if (x[0].childNodes[j].nodeType != 1) continue;
            var container = document.createElement('TH');
            theData = document.createTextNode(x[0].childNodes[j].nodeName);
            container.appendChild(theData);
            row.appendChild(container);
    }
    tmp.appendChild(row);
    for (i=0;i<x.length;i++)
    {
            var row = document.createElement('TR');
            for (j=0;j<x[i].childNodes.length;j++)
            {
                    if (x[i].childNodes[j].nodeType != 1) continue;
                    var container = document.createElement('TD');
                    var theData = document.createTextNode(x[i].childNodes[j].firstChild.nodeValue);
                    container.appendChild(theData);
                    row.appendChild(container);
            }
            tmp.appendChild(row);
    }
    document.getElementById('writeroot').appendChild(newEl);
}
</script>
</HEAD>

<BODY onLoad="javascript:importXML();">
<p id=writeroot> </p>
</BODY>

Untuk info lebih lanjut lihat http://www.easycodingclub.com/xml-parser-in-javascript/javascript-tutorials/ ini

klub easycoding
sumber
0

Penafian : Saya telah membuat fast-xml-parser

Saya telah membuat fast-xml-parser untuk mengurai string XML menjadi objek JS / JSON atau objek traversal menengah. Ini diharapkan kompatibel di semua browser (namun hanya diuji pada Chrome, Firefox, dan IE).

Pemakaian

var options = { //default
    attrPrefix : "@_",
    attrNodeName: false,
    textNodeName : "#text",
    ignoreNonTextNodeAttr : true,
    ignoreTextNodeAttr : true,
    ignoreNameSpace : true,
    ignoreRootElement : false,
    textNodeConversion : true,
    textAttrConversion : false,
    arrayMode : false
};

if(parser.validate(xmlData)){//optional
    var jsonObj = parser.parse(xmlData, options);
}

//Intermediate obj
var tObj = parser.getTraversalObj(xmlData,options);
:
var jsonObj = parser.convertToJson(tObj);

Catatan : Itu tidak menggunakan parser DOM tetapi mengurai string menggunakan RE dan mengubahnya menjadi objek JS / JSON.

Cobalah online , CDN

Amit Kumar Gupta
sumber
-1

Anda juga dapat melalui fungsi jquery ($. ParseXML) untuk memanipulasi string xml

contoh javascript:

var xmlString = '<languages><language name="c"></language><language name="php"></language></languages>';
var xmlDoc = $.parseXML(xmlString);
$(xmlDoc).find('name').each(function(){
    console.log('name:'+$(this).attr('name'))
})
pengguna6016338
sumber