JavaScript
Børre Stenseth
JSON >Eksempel1

Vin som JSON

Hva

I dette eksempelet brukes, foruten JSON, AJAX, XSLT, Python, Database.

Vi bruker dessuten en datakilde som inneholder vinanmeldelser. Disse datene er tilgjengelige både som XML og i en enkel database. Detaljer er beskrevet på siden : DATA.

I korthet er hver vin beskrevet med følgende XML-node:

<wine>
	<type>sparkling</type>
	<name>Comte de Noiron Coeur de Cuvée, Brut</name>
	<catalog>14693</catalog>
	<country>Frankrike</country>
	<volume>75</volume>
	<price>224.90</price>
	<dice>4</dice>
	<description>Test. Duft av modne epler og gjær....</description>
</wine> 

AJAX

Det interessante med denne angrepsvinkelen er altså at vi får svært enkel koding på klientsiden. Vi får tilgang til objekter og kan plukke attributter etter ønske.

Hvis vi ser dette i en AJAX situasjon, har vi følgende:

fig0
Produksjon av JSON

Hvorvidt bruk av JSON er en effektiv og/eller enkel metode avhenger av hvordan dataene våre er representerte på tjeneren, og det avhenger av hva vi må gjøre med dem på klienten. Det er klart at dersom vi skal overføre en hel fil som er ferdiglagd som et HTML-fragment og vi skal plassere dette fragmentet samlet på klienten er det mest effektive å bruke ren tekst slik:

	document.getElementById("target").innerHTML= myRequest.responseText

Dersom teksten som kommer tilbake består av mange "deler" som skal plasseres på forskjellige steder på siden stiller saken seg litt annerledes. Både kommaseparert tekst, XML og JSON kan være alternativer.

På tjenersiden vil mye avhenge av dataformatet og programmeringsverktøyet vi har til rådighet. Som regel kan vi vel regne med at programmeringsverktøyet på tjeneren er bedre og raskere enn JavaScript. Dette skulle i så fall tale for at så mye som mulig gjøres klart på tjeneren.

På den annen side er det ofte slik at bruken av de data vi sender tilbake vil endre seg i forskjellige situasjoner avhengig av bruksønsker og designbeslutninger. Det er kanskje en fordel å lage en generell tjenerfunksjon og så lage spesielle klientløsninger etter ønske. Dette taler for et fleksibelt format som peker i retning av JSON, eller XML. De to, JSON og XML, kan langt på vei sidestilles prinsippielt, men JSON gjør trolig lettere å programmere på klienten.

Nedenfor skal vi gå gjennom noen eksempler på pakking av data på tjenersiden og bruk på klientsiden. Vi skal bruke vindataene som gjennomgangseksempel. Vi skal bruke både XML-versjonen og databaseversjonen. Vi skal i alle tilfellene lage en klientside som gir oss mulighet for å velge vin av en bestemt type (rød, hvit, rose, musserende) og fra et bestemt land. Vi skal i alle løsningen bruke JSON, selv om et par av eksemplene åpenbart kunne løses med lettere med tekst og alle kunne løses med XML.

Vin som JSON

I alle eksemplene bruker vi et JSON format som ser slik ut, vist med linjeskift:

	{"diagnose":"OK",
	 "overskrift":"Rødvin fra Island",
	"viner":[
	{"navn":"Masi","terning":"4","beskrivelse":"OK"},
	{"navn":"Perequita","terning":"5","beskrivelse":"God"},
	...
	]}

Altså en diagnose som sier om dataoppslaget har gått bra eller ikke, en passelig overskrift pluss en array med vinobjekter. Merk at vi pakker dataene uten linjeskift slik at de kan leses som en sammenhengende string i JavaScript.

I alle eksemplene bruker vi samme javascript på klienten:

_script1.js
// relies on jquery
function getIt(address,form,targetNodeId)
{
    var params="vintype="+form.vintype.value+"&land="+form.land.value;
    $.ajax({
    url:address,
    data:params,
    success:function(data){
        processJSON(data,targetNodeId);
    },
    error:function(data){
        $('#'+targetNodeId).html("Could not access content");
    }
    });
}
function processJSON(S,targetId)
{
    var ob = null;
    try{
        ob = JSON.parse(S);
    }
    catch(ex){
        //console.log(S);
        $('#'+targetId).html('<p>Feil i dataformatet: '+ex.message+'</p>');
        return;
    }
    var dia=ob.diagnose;
    if(dia.indexOf('OK')==0){
        var vinlist=ob.viner;
        var S='';
        for(var ix=0;ix<vinlist.length;ix++){
              S+='<p>'+
                  '<span style="font-size:20px;color:blue;margin-right:20px">'+
                  vinlist[ix].terning+'</span>'+
                  vinlist[ix].navn+'<br/>'+
                  vinlist[ix].beskrivelse+'<br/></p>';
        }
        S='<h1>'+vinlist.length+' '+ob.overskrift+'</h1>'+S;
        $('#'+targetId).html(S);
    }
    else{
        document.getElementById(targetId).innerHTML='<pre>'+dia+'</pre>';
    }
}

En typisk tekst som overføres og parses ser slik ut: typisk json-string

Vin fra XML

fig1
Produksjon av JSON fra XML

Vi bruker XML-data på tjeneren, skriver DOM-code som identifiserer de vinene vi er interesserte i og produserer JSON. På klientsiden lager vi HTML av JSON-formatet.

Du kan teste her https://borres.hiof.no/wep/js/case1/page1.html

Koden på tjeneren ser slik ut:

_jsonvin1.py

Vin fra XML via XSLT

fig2
Produksjon av JSON fra XML med XSL

Vi bruker XML-data på tjeneren, skriver en XSLT-transformasjon som lager JSON direkte. På klientsiden lager vi HTML av JSON-formatet.

Du kan teste her https://borres.hiof.no/wep/js/case1/page2.html

Koden på tjeneren ser slik ut:

_jsonvin2.py

Transformasjonen er slik:

_trans2.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
  <xsl:param name="theCountry" select="'Frankrike'"/>
  <xsl:param name="theType" select="'red'"/>
  <xsl:template match="/">
    "viner":[
    <xsl:apply-templates 
         select="//wine[country=$theCountry and type=$theType]">
      <xsl:sort order="descending" select="dice"/>
    </xsl:apply-templates>
    ]
  </xsl:template>
  <xsl:template match="//wine">
    {"terning":"<xsl:value-of select="dice"/>",
     "navn":"<xsl:value-of select="name"/>",
    "beskrivelse":"<xsl:value-of select="description"/>"}
    <xsl:if test="position() != last()">
                    <xsl:text>,</xsl:text>
     </xsl:if>
  </xsl:template>
</xsl:stylesheet> 

Vin fra database

fig3
Produksjon av JSON fra DB

Vi bruker en database på tjeneren og lager JSON basert på de recordene vi plukker opp med en SQL-setning. På klientsiden lager vi HTML av JSON-formatet.

Du kan teste her https://borres.hiof.no/wep/js/case1/page3.html

Koden på tjeneren ser slik ut:

_jsonvin3.py
JSON >Eksempel1