HTML5
DOM
HTML
Børre Stenseth

DOMParser

Hva

Vi kan bruke parseren i nettleseren til å parse egne filer og opprette DOM-objekter som kan leses og manipuleres på samme måte som vi kan lese og manipulere elementer i en webside. Du finner en introduksjon til temaet på Mozilla developers network [1] . Vi skal se på tre enkle eksempler, HTML, XML og SVG.

Vi gjør det så enkelt at vi lager stringer som Javascript-variable og parser disse stringene. Det er selvsagt ikke noe i veien for at vi henter teksten ved hjelp av AJAX, hvilket vel er det vi vanligvis vil gjøre.

HTML

Vi lager oss en enkel, komplett webside som en Javaskript-string.
(\ bak hver linje for å få en sammenhengende text på flere linjer)

_page.js
var THTML='<!DOCTYPE HTML>\
<html lang="no">\
<head>\
    <title>readme</title>\
    <meta charset="UTF-8"/>\
</head>\
<body>\
<div id="findme">\
OK, her er det\
</div>\
</body>\
</html>';

Vi behandler teksten og lager et document slik:

_doHTML
function doHTML(){
    var parser = new DOMParser();
    var doc = parser.parseFromString(THTML, "text/html");
    var S=doc.getElementById("findme").innerHTML;
    document.getElementById("dumptext").innerHTML=S;
}

XML

Vi lager oss et enkelt XML-dokument, som en javaskript-string:

_medlemmer.js
var medlemmer='<?xml version="1.0" encoding="UTF-8"?>\
<medlemmer>\
<medlem>\
    <navn>Ole</navn>\
    <by>Moss</by>\
</medlem>\
<medlem>\
    <navn>Jens</navn>\
    <by>Moss</by>\
</medlem>\
<medlem>\
    <navn>Kari</navn>\
    <by>Sarpsborg</by>\
</medlem>\
<medlem>\
    <navn>Per</navn>\
    <by>Sarpsborg</by>\
</medlem>\
<medlem>\
    <navn>Frits</navn>\
    <by>Halden</by>\
</medlem>\
</medlemmer>';

Vi behandler teksten og lager et document slik:

_doXML
function doXML(){
    var parser = new DOMParser();
    var xmldoc = parser.parseFromString(medlemmer, 
                                        "application/xml");
    var elt=document.getElementById("dumpxml");
    elt.innerHTML="";
    
    var resT="";
    var path='//medlem/navn';
    var nodes=xmldoc.evaluate(path, xmldoc, null, 
                            XPathResult.ANY_TYPE, null);
    var result=nodes.iterateNext();
    var resT="";
    while(result){
        resT+=result.childNodes[0].nodeValue + "</br>";
        result=nodes.iterateNext();
    }            
    elt.innerHTML=resT;
}

SVG

Vi lager oss et enkelt SVG-element, som en javaskript-string:

_flagget.js
flagget='<svg version="1.1" xmlns="http://www.w3.org/2000/svg" \
            width="300px" height="300px"  viewBox="0 0 300 300">\
  <desc>\
  Flaggets proposjoner:\
  Horisontalt: 6R 1H 2B 1h 12R=22\
  Vertikalt:   6R 1H 2B 1H 6R=16\
  </desc>\
    <g transform="translate(20,50)">\
      <rect x="0" y="0" width="220" height="160" \
      fill="red" stroke="none" stroke-width="0"/>\
      <rect x="0" y="60" width="220" height="40" \
      fill="white" stroke="none"/>\
      <rect x="60" y="0" width="40" height="160" \
      fill="white" stroke="none"/>\
      <rect x="0" y="70" width="220" height="20" \
      fill="blue" stroke="none"/>\
      <rect x="70" y="0" width="20" height="160" \
      fill="blue" stroke="none"/>\
      <g transform="translate(0,225)">\
        <text id="TextElement" x="0" y="0"\
          font-family="Verdana" font-size="25" \
          fill="black" stroke="none"> \
          17.mai\
        </text>\
      </g>\
   </g>\
</svg>';

Vi behandler teksten og lager et document slik:

_doSVG
function doSVG(){
    var parser = new DOMParser();
    var svgdoc = parser.parseFromString(flagget, 
                                        "image/svg+xml");
    var elt=document.getElementById("dumpflag");
    elt.innerHTML="";
    
    // forutsetter at svg har correct header: version and namespace
    var svgNode=svgdoc.documentElement;
    elt.appendChild(document.importNode(svgNode, true));
}

Feilhandtering

Det er desverre slik at DOMParser metoden parseFromString ikke kaster noen feilmelding (exception). Vi skal neden for se hvordan vi finne ut om noe går galt. Ingen garantier for at dette vil være vantett.

HTML

HTML-parsingen er svært tolerant og aksepterer store avvik fra velformet HTML/XML, akkurat som vi kjenner det fra parsing av websider i sin allminnelighet

Vi lager oss en meningsløs text og forsøker å behandle den som en HTML-side.

_Xpage.js
var XTHTML='jabado<div id="findme">tja</dav>';

Vi kan vanskelig lage en dårligere innramming av det elementet vi leter etter, og finner.

Vi behandler teksten og lager et document slik:

_doXHTML
function doXHTML(){
    var dumpElt=document.getElementById("Xdumptext");
    try{
        var parser = new DOMParser();
        var doc = parser.parseFromString(XTHTML, "text/html");
        var S=doc.getElementById("findme").innerHTML;
        dumpElt.innerHTML=S;
    }
    catch(e){
        console.log(e);
        dumpElt.innerHTML=e;
    }
}

XML

XML-parsing er pr definisjon ikke tolerant i det hele tatt. Vi forventer og forlanger velformet XML. Nr parseren ikke fikser jobben returnerer den en XML-fil med feilbeskrivelse. Vi må altså kunne gjenkjenne denne XML-fila. Vi kan gjøre dette ved å identifisere rotelementet som <parsererror>.

Vi lager oss et XML-dokument med en enkel feil (medlam i stedet for medlem), som en Javaskript-string:

_Xmedlemmer.js
var Xmedlemmer='<?xml version="1.0" encoding="UTF-8"?>\
<medlemmer>\
<medlem>\
    <navn>Ole</navn>\
    <by>Moss</by>\
</medlem>\
<medlem>\
    <navn>Jens</navn>\
    <by>Moss</by>\
</medlam>\
<medlem>\
    <navn>Kari</navn>\
    <by>Sarpsborg</by>\
</medlem>\
<medlem>\
    <navn>Per</navn>\
    <by>Sarpsborg</by>\
</medlem>\
<medlem>\
    <navn>Frits</navn>\
    <by>Halden</by>\
</medlem>\
</medlemmer>';

Vi behandler teksten og lager et document slik:

_doXXML
function doXXML(){
    var dumpelt=document.getElementById("Xdumpxml");
    dumpelt.innerHTML="";
    try{
        var parser = new DOMParser();
        var xmldoc = parser.parseFromString(Xmedlemmer, 
                                            "application/xml");
        var docelt=xmldoc.documentElement;
        // something wrong ?
        if(docelt.nodeName=="parsererror"){
            var T=docelt.firstChild.textContent;
            throw(T);
        }
        // it is ok
        var resT="";
        var path='//medlem/navn';
        var nodes=
            xmldoc.evaluate(path, xmldoc, null, 
                            XPathResult.ANY_TYPE, null);
        var result=nodes.iterateNext();
        var resT="";
        while(result){
            resT+=result.childNodes[0].nodeValue + "</br>";
            result=nodes.iterateNext();
        }            
        dumpelt.innerHTML=resT;
    }
    catch(T){
        T=T.replace(new RegExp('<', 'g'), '&lt;')
            .replace(new RegExp('>', 'g'), '&gt;');
        console.log(docelt,T);
        dumpelt.innerHTML=T;
    }
}

Referanser