
W tym artykule przejrzymy metody pracy z formatem XML w JavaScript. O przetwarzaniu XML w JavaScript wspomnieliśmy już we wstępie do AJAX. Dziś nieco rozwiniemy temat, i oczywiście poszukamy rozwiązań wspomagających nas w zadaniach związanych z XML.
XML w JavaScript
Chociaż w JavaScript prawdopodobnie częściej pracuje się z formatem JSON, to jednak czasami trzeba zająć się danymi w formacie XML. Na przykład osobiście preferuję JSON, ale integrując aplikację z zewnętrznym API klienta zostaje narzucony XML.
Przejdźmy do przykładów. Zacznijmy od prostej, testowej struktury XML, zdefiniowanej jako łańcuch w JavaScript.
var inputXML = '<?xml version="1.0" ?><root>Tester</root>';
Zmienna inputXML to zwykły string. Przedstawiona poniżej funkcja zajmuje się przetworzeniem zwykłego łańcucha na obiekt, na którym będziemy mogli operować w JavaScript.
function stringToXML(text) { try { var xml = null; if (window.DOMParser) { var parser = new DOMParser(); xml = parser.parseFromString(text, "text/xml"); var foundErr = xml.getElementsByTagName("parsererror"); if ( !foundErr || !foundErr.length || !foundErr[0].childNodes.length) { return xml; } return null; } else { xml = new ActiveXObject("Microsoft.XMLDOM"); xml.async = false; xml.loadXML(text); return xml; } } catch (e) { ; } }
Używając tej funkcji, tworzymy obiekt na podstawie łańcucha zawierającego XML i przetwarzamy go:
var xmldoc = stringToXML(inputXML); var root_node = xmldoc.getElementsByTagName('root').item(0); alert(root_node.firstChild.data);
Gdy spróbujmy wykonać:
alert(xmldoc);
otrzymamy w wyniku [object XMLDocument]. I dobrze – tego chcieliśmy pisząc funkcję stringToXML.
W drugą stronę
Natomiast co jeśli mamy taki właśnie obiekt i chcemy przetworzyć go na łańcuch, choćby w celu przejrzenia jego struktury? Wykonujemy operację odwrotną, co prezentuje poniższy kod:
function xmlToString(objXML) { if (window.ActiveXObject) { return objXML.xml; } else { return (new XMLSerializer()).serializeToString(objXML); } } // przykład użycia: alert(xmlToString(xmldoc)); // wynik: <?xml version="1.0" encoding="UTF-8"?><root>Tester</root>
Praca z łańcuchem znaków
Ktoś może powiedzieć, że chce jedynie pobrać wartość z łańcucha tekstowego zawierającego prosty XML, bez dodatkowych operacji. Cóż, można napisać funkcję operującą bezpośrednio na łańcuchu zawierającym XML.
Do przykładu użyjemy takich danych wejściowych:
var inputXML = '<?xml version="1.0" ?><root><title>Testowy</title>'; inputXML += '<content>Lorem ipsum...</content></root>';
Przetwarzamy łańcuch w JavaScript:
function getXmlValue(input, xmlMarkup) { var beg = ""; var end = ""; var dt = 0; var xmlVal = ""; var start = "<" + xmlMarkup + ">"; var stop = "</" + xmlMarkup + ">"; beg = input.indexOf(start); end = input.indexOf(stop); dt = start.length; if ( (beg !== false) && (end !== false) ) { xmlVal = input.substr(beg + dt, end - beg - dt); } return xmlVal; } alert(getXmlValue(inputXML, 'content'));
W drugim argumencie podajemy nazwę tagu, spod którego chcemy wyciągnąć dane. Funkcja jest w zasadzie trywialna, ale naprawdę bywała przydatna w starszych projektach.
Konwersja XML na tablicę JavaScript
Zmienialiśmy już łańcuch na obiekt poprzez funkcję stringToXML(). Przyda nam się ona jeszcze w kolejnym przykładzie, gdzie pójdziemy krok dalej i przetworzymy obiekt na wygodną w użyciu tablicę JavaScript.
Zajmie się tym następująca funkcja:
function xmlToJsArray(rawXmlData) { var output = new Array(); var i, j, rec, obj; for (i = 0; i < rawXmlData.childNodes.length; i++) { if (rawXmlData.childNodes[i].nodeType == 1) { rec = rawXmlData.childNodes[i]; obj = output[output.length] = new Object(); for (j = 0; j < rec.childNodes.length; j++) { if (rec.childNodes[j].nodeType == 1) { obj[rec.childNodes[j].tagName] = rec.childNodes[j].firstChild.nodeValue; } } } } return output; } // przykład użycia var arr = xmlToJsArray(stringToXML(inputXML)); // w naszym przykladzie wynikiem będzie: // '0' ... // 'title' => "Testowy" // 'content' => "Lorem ipsum..." // odwołanie w postaci: alert(arr[0]['title']);
I tym samym mamy dane z XML w tablicy JavaScript, którą wygodniej jest przetwarzać.
Użycie jQuery do przetwarzania XML w JavaScript
Jak można by się spodziewać, framework jQuery udostępnia nam wsparcie przy pracy z XML w JavaScript.
Podstawą będzie jQuery.parseXML: http://api.jquery.com/jQuery.parseXML/.
Przykład użycia:
var xml = "<rss version='2.0'><channel><title>The Title"; xml += "</title></channel></rss>"; jQuery(document).ready(function($) { xmlDoc = $.parseXML(xml); $xml = $(xmlDoc); $title = $xml.find("title"); // get value alert($title.text()); // set value $title.text("XML Title"); });
Z jQuery wszystko co trzeba wykonamy w kilku linijkach kodu.
Nie brakuje także plugin’ów jQuery dedykowanych obsłudze XML, takich jak jParse: http://jparse.kylerush.net/.
Podsumowanie
Na tym kończymy krótki przegląd metod obsługi XML w JavaScript. Z pewnością jest ich więcej – tutaj bazowaliśmy na doświadczeniach z własnych projektów.
Dziękuję za uwagę.