2009-03-16 9 views
184

Ho una stringa variabile che contiene XML ben formato e valido. Devo usare il codice JavaScript per analizzare questo feed.Analisi XML di una stringa variabile in JavaScript

Come posso realizzare questo utilizzando il codice JavaScript (compatibile con il browser)?

+0

ho creato ad alte prestazioni [XML Parser] (https://github.com/NaturalIntelligence/fast-xml-parser). Dai un'occhiata per il confronto con altre librerie. –

risposta

85

Update: Per una risposta più corretta vedere Tim Down's answer.

Internet Explorer e, ad esempio, i browser basati su Mozilla espongono diversi oggetti per l'analisi XML, quindi è consigliabile utilizzare un framework JavaScript come jQuery per gestire le differenze tra browser.

Un esempio davvero di base è:

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

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

Nota: Come sottolineato nei commenti; jQuery non esegue realmente alcun parsing XML, si affida al metodo innerHTML DOM e lo analizzerà come se fosse un qualsiasi HTML, quindi fai attenzione quando usi i nomi di elementi HTML nel tuo XML. Ma penso che funzioni abbastanza bene per il semplice 'parsing' XML, ma probabilmente non è suggerito per l'analisi XML intensiva o 'dinamica' in cui non si anticipa quale XML verrà eliminato e questo test se tutto analizza come previsto.

+6

Il codice per l'astrazione della differenza nell'analisi XML tra IE e altri browser è poche righe banali, quindi non vale la pena di avvitarsi su 50K di jQuery per conto suo. Manipolare il DOM dell'XML risultante è un'altra questione. –

+7

E qualcosa che non avevo realizzato al momento di postare il mio commento precedente è che jQuery non analizza nemmeno l'XML, semplicemente lo assegna come la proprietà 'innerHTML' di un elemento, che non è affatto affidabile. –

+0

Si noti che JQuery non supporta gli spazi dei nomi XML. Vedi http://www.zachleat.com/web/2008/05/10/selecting-xml-with-javascript/ – mikemaccana

2

Si prega di dare un'occhiata al XML DOM Parser (W3Schools). È un tutorial sull'analisi del DOM XML. L'attuale parser DOM differisce da browser a browser ma l'API DOM è standardizzata e rimane la stessa (più o meno).

In alternativa, utilizzare E4X se è possibile effettuare lo restrict in Firefox. È relativamente più facile da usare ed è parte di JavaScript dalla versione 1.6. Ecco un piccolo esempio dell'uso ...

//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. 
1

Supponendo di voler creare un DOM da questo XML, purtroppo è necessario utilizzare interfacce specifiche del browser. Here è un tentativo di una funzione cross-browser per farlo, tuttavia.

W3Schools also document i singoli metodi specifici del browser.

19

La maggior parte degli esempi sul Web (e alcuni presentati sopra) mostrano come caricare un file XML da un file in un browser compatibile. Questo si rivela facile, tranne nel caso di Google Chrome che non supporta il metodo document.implementation.createDocument(). Quando si utilizza Chrome, per caricare un file XML in un oggetto XmlDocument, è necessario utilizzare l'oggetto XmlHttp incorporato e quindi caricare il file passando l'URI.

Nel tuo caso, lo scenario è diverso, perché si vuole caricare il codice XML da una variabile stringa, non un URL. Tuttavia, per questo requisito, Chrome funziona come Mozilla (o almeno così ho sentito) e supporta il metodo parseFromString().

Ecco una funzione che uso (è parte della libreria di compatibilità del browser Attualmente sto costruendo):

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

-1 per lo sniffing del browser. –

+14

Sono a conoscenza delle opinioni controverse riguardanti lo sniffing di Browser e questo è il motivo per cui non ho incluso questa funzione qui. Tuttavia, non è stato stabilito che sia SBAGLIATO. In ogni caso, questo è un esempio * suggestivo *. – Cerebrus

+1

Credo che sia sbagliato in quanto non si può garantire che sia giusto. Chiunque può spoofare le stringhe UA, ed è improbabile che OGNI browser non IE supporti DOMParser e che lo sniffing del tuo browser sia PERFETTO. Inoltre, è molto più semplice farlo nel modo giusto: 'if (window.ActiveXObject) {...}' – 1j01

8

ho sempre usato l'approccio di sotto della quale funziona in IE e Firefox.

Esempio XML:

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

Come prenderesti un valore se avessi questa situazione valore? – Siblja

+1

@Siblja è necessario utilizzare 'innerText' invece di' getAttribute() ' – Manux22

1

ho creato un plugin jQuery che analizza XML piuttosto facilmente. Funziona con tutti i browser di grado A di Yahoo e viene fornito con opzioni di filtro, limite e callback.

Potrebbe essere una soluzione da prendere in considerazione: http://jparse.kylerush.net/

301

risposta Aggiornato per il 2017

Di seguito vi analizzare un XML stringa in un documento XML in tutti i principali browser. A meno che non hai bisogno di supporto per IE < = 8 o qualche oscuro del browser, è possibile utilizzare la seguente funzione:

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

Se è necessario supportare IE < = 8, il seguente farà il lavoro:

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

una volta che avete un Document ottenuto tramite parseXml, è possibile utilizzare i soliti DOM traversal metodi/proprietà quali childNodes e getElementsByTagName() per ottenere i nodi che si desidera .

Esempio utilizzo:

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

Se stai usando jQuery, a partire dalla versione 1.5 è possibile utilizzare la sua built-in parseXML() metodo, che è funzionalmente identico alla funzione di cui sopra.

var xml = $.parseXML("<foo>Stuff</foo>"); 
alert(xml.documentElement.nodeName); 
+51

Sono d'accordo, questa dovrebbe essere accettata risposta. La mia risposta è così antica fin dai primi giorni, ho sempre trovato curioso di ottenere ancora voti positivi. Qualcuno in favore di rimuovere la mia risposta accettata? Ed il sistema di voto è difettoso? Votate questo popolo! –

+0

@SanderVersluys: sei in grado di rimuovere la tua risposta? – Witman

+0

@Witman in effetti, non posso perché è la risposta accettata ... ho aggiornato la mia risposta per riflettere che ... –

13

Marknote è un bel leggero cross-browser JavaScript parser XML. È orientato agli oggetti e ha un sacco di esempi, oltre allo API è documentato. È abbastanza nuovo, ma finora ha funzionato bene in uno dei miei progetti. Una cosa che mi piace è che legge XML direttamente da stringhe o URL e puoi anche usarlo per convertire l'XML in JSON.

Ecco un esempio di cosa si può fare con 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") + "'" 
    ); 
} 
+0

Sembra che [marknote] (https://code.google.com/p/marknote/) implementa un parser javascript puro. Significa che dovrebbe essere compatibile con qualsiasi motore javascript, ovunque sia utilizzato in un browser, in node.js o in un motore javascript standalone ... – Coyote

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> 

Per maggiori informazioni consultare questo http://www.easycodingclub.com/xml-parser-in-javascript/javascript-tutorials/

-1

È anche possibile attraverso la funzione di jQuery ($.parseXML) per manipolare stringa XML

esempio 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')) 
}) 
0

Diniego: Ho creato fast-xml-parser

ho creato fast-xml-parser ad analizzare una stringa XML in JS oggetto/JSON o oggetto trasversale intermedio. Dovrebbe essere compatibile con tutti i browser (comunque testato solo su Chrome, Firefox e IE).

Uso

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

Nota: Non usa parser DOM, ma analizzare la stringa utilizzando RE e convertirlo in oggetto JS/JSON.

Try it online, CDN

Problemi correlati