XML w JavaScript

xml

Poziom średnio-zaawansowany

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ę.

Programista WWW i aplikacji mobilnych z wieloletnim doświadczeniem, początkujący bloger. Pasjonat programowania, nowych technologii, e-commerce, a także sportu i motoryzacji.

Twitter LinkedIn Google+ Skype Xing 

Podaj dalej: Share on Facebook0Tweet about this on TwitterShare on Google+1Share on LinkedIn0Share on Tumblr0Digg thisEmail this to someonePin on Pinterest1
Możesz skomentować leave a response, lub podać trackback z własnej strony.