Gern stehe ich zur fachlichen Unterstützung in XML-Technologien, C#.NET, VisualBasic.NET und Java zur Verfügung. Sprechen Sie mich einfach an: Mail oder ☎ 0151 . 750 360 61


XPath 3.0, XPath 2.0, XPath 1.0 / XPath-Funktionen / XPath: Sequenz-Funktionen / JSON

JSON

JSON

➪ JSON, die JavaScript-Object-Notation, ist ein textbasiertes Datenformat, das XML an Flexibilität am nächsten kommt. Zahlreiche REST-Webservices bieten neben XML auch JSON zur freien Auswahl an (auch CSV oder Text). Daher ist die Konvertierung von XML nach JSON eine häufige Aufgabe.

Auf dieser Seite:

Siehe auch JSON-Auswertung mit C#.NET

JSON ist die Abkürzung von Java Script Object Notation. JSON bietet die Möglichkeit, JavaScript-Objekte in einem String abzubilden.

{ ... } deklariert ein Objekt.
{ "property":"value" } deklariert ein Feld "property" innerhalb eines Objekts und weist ihm den Wert "value" zu. Die "" besagen, dass es sich dabei um einen String handelt.
{ "zahl": 9 } deklariert ein Feld "zahl" innerhalb eines Objekts und weist ihm den Wert 9 zu. Da die Hochkommata "" fehlen, handelt es sich um eine Zahl.
{ "stimmt": true } deklariert ein Feld "stimmt" innerhanl eines Objekts und weist ihm den Wert true zu. Da die Hochkommata "" fehlen, handelt es sich um einen Boolean-Wert.
[ ... ] deklariert ein leeres Array.
[ {...}, {...} ] deklariert ein Array mit zwei Objekten.

Ein JSON-Beispiel sieht so aus:


[{"id":"1","name":"Holzflos","vorname":"Hugo"},
{"id":"2","name":"Sagblos","vorname":"Stefan"},
{"id":"8","name":"Rhodos","vorname":"Rudi"},
{"id":"15","name":"Kolos","vorname":"Karl"},
{"id":"19","name":"Lustlos","vorname":"Ludwig"},
{"id":"10","name":"Ruhelos","vorname":"Rita"},
{"id":"11","name":"Schlaflos","vorname":"Susi"},
{"id":"12","name":"Rielos","vorname":"Lotte"},
{"id":"13","name":"Muehelos","vorname":"Martin"},
{"id":"14","name":"Leinenlos","vorname":"Liane"}]

Bereits mit XSLT 1.0 ist es möglich, aus XML den vorstehenden JSON-String zu generieren.


<xsl:stylesheet version="1.0" 
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text"/>
  <xsl:template match="/">
<xsl:text>[</xsl:text>
  <xsl:for-each 
       select="Orte/Ort/Mensch[Gehalt &lt; 500]">
    <xsl:text>{</xsl:text>
    <xsl:for-each select="child::*[position() &lt; 4]">
      <xsl:text>"</xsl:text>
      <xsl:value-of select="local-name()"/>
      <xsl:text>":"</xsl:text>
      <xsl:value-of select="."/>
      <xsl:text>"</xsl:text>
      <xsl:if test="position() != last()">
      <xsl:text>,</xsl:text>
      </xsl:if>
    </xsl:for-each>    
    <xsl:text>}</xsl:text>
    <xsl:if test="position() != last()">
      <xsl:text>,
</xsl:text>
    </xsl:if>
  </xsl:for-each>  
<xsl:text>]</xsl:text>
  </xsl:template>
</xsl:stylesheet>

XML oder JSON?

JSON ist ein Datenformat, XML ist eine Sprache. Der Vergleich von JSON mit XML ist daher ähnlich sinnlos wie der Vergleich zwischen CSV und C#.NET.

XML-Technologien wie , XQuery, , Schematron, XSpec, und viele andere sind deklarativ-funktionale Programmiersprachen der 4. Generation. In XML-Technologien kommt alles aus einer Hand: Detaildokumente mit flexiblen Zeichensätzen, Instrumente zu deren Strukturdefinition, Dokumentation und Validierung, Transformation in unterschiedliche Zielformate, Testing.

Obwohl die Paradigmen der objektorientierten Programmierung sehr populär sind, wäre es verfehlt, den sehr umfangreichen Kontext der XML-Technologien mit OOP-Maßstäben beurteilen zu wollen. Objektorientierung ist durchaus nicht das Maß aller Dinge; SQL ist auch nicht objektorientiert.

Zwischen Objektorientierung und XML als Datenaustauschformat gibt es einen ähnlichen Unterschied wie zwischen Objektorientierung und SQL. SQL-Datensätze sind keine serialisierten Java- oder C#.NET-Objekte. Objekte sind Daten plus Funktionalität. Werden Informationen in relationalen SQL-Datenbanktabellen abgespeichert, dann müssen jene Daten erst einen Konvertierungsprozess durchlaufen, bevor sie objektorientiert verwendet werden können.

Das Gleiche gilt, wenn Daten mithilfe von XML, JSON, CSV, Flatfiles, EDIFACT etc. ausgetauscht werden. Auch hier sind (teils mehrstufige) Konvertierungsprozesse notwendig, bevor die Daten in einer Form vorliegen, die von einem anschließend startenden Programm verarbeitet werden können. Die letztliche Verwendung dieser Daten ist keineswegs ausschliesslich objektorientierten Programmen vorbehalten: Von Maschinencode über Assembler, prozeduraler/objektorientierter bis hin zu deklarativ/funktionalen Programmen ist alles vorstellbar.

Es ist daher nicht angebracht, XML auf Aspekte der Objektserialisierung reduzieren zu wollen. In diese Richtung zielt der häufig bemängelte XML-Wortreichtum: JSON sieht wesentlich schlanker, damit ressourcenschonender aus. Ich kann das Argument nur bedingt nachvollziehen.

Vergleichen Sie ein XML-Dokument (in einem konkreten Beispiel 8871 Zeichen ohne Prolog), das so weit wie möglich nicht in der Element-, sondern in der Attributschreibweise geschrieben ist und in dem alle unnötigen Whitespaces entfernt sind, mit einem analogen JSON-Dokument desselben Inhalts (8511 Zeichen), so liegt der XML-"Overhead" in diesem Beispiel gerade einmal bei vier Prozent (360 Zeichen). Umfangreichere Studien belegen, dass gezipptes XML und JSON etwa dieselbe Dateigröße ergibt.

Wer freilich die Elementschreibweise wählt, wo jedes Start-Tag notwendigerweise ein Ende-Tag haben muss, und obendrein eine für das menschliche Auge leicht lesbare Darstellung mit zahlreichen Whitespaces nutzt, der kommt schnell auf den doppelten Umfang.

Ein zweites Argument besagt, dass JSON-Strings unmittelbar in Objekte konvertiert werden können. Dieses Argument mag für Sprachen wie JavaScript und PHP stimmen, die ein dynamisches Objektmodell aufweisen: Hier können Objekten zur Laufzeit Properties hinzugefügt werden, ohne dass dafür eine Klasse vorhanden sein muss.

Die Aussage stimmt jedoch nicht bei Sprachen wie Java, C++, C#.NET, denen ein Template-basiertes Objektmodell zugrunde liegt: Bevor ein Objekt instanziiert werden kann, muss die Klasse bereits vorliegen. Daher ist die Objektkonvertierung von JSON-Strings in Java-, C++, C#-Objekte keineswegs eine triviale Sache.

XML bietet den großen Vorteil, präzise versionierte Namensräume mit klar dokumentierbaren Definitionen der Einzelbegriffe vorhalten zu können. JSON bietet hier im Draft das Konzept des lightweight Linked Data format (JSON-LD) an.

In XML-Schema ist jede komplexe Struktur mit jedem einzelnen Datenfeld hinsichtlich seines Namensraums und Datentyps klar definierbar. Beides bietet die Grundlage der Validierung der Einzeldokumente und der zuverlässigen Programmierung der Konvertierungslogiken. In JSON ist derzeit JSON-Schema (http://json-schema.org/) im Draft-Modus verfügbar. Dessen Autoren haben viel Arbeit investiert, einen Entwurf für JSON Schema Core, JSON Schema Validation, JSON Hyper-Schema sowie relative JSON Pointers vorzulegen.

Richtig ist die Notwendigkeit sauberer Struktur- und Typdefinitionen in grundsätzlich allen Formaten, auch bei XML und JSON, denn hier wie dort steht der Progammierer vor der Aufgabe, eine hohe Datenqualität absichern zu müssen, um Logiken schreiben zu können, die einen Output ohne Informationsverlust garantieren. Die Tools stehen also zur Verfügung: Werden sie auch genutzt?

JSON-Auswertung mit JavaScript

JSON findet beispielsweise Anwendung im Datenaustausch zwischen Client und Server im Rahmen dynamischer Webseiten (client-/browserseitige DOM-Programmierung, häufig im Zusammenhang mit AJAX). Der Vorzug liegt darin, dass der JavaScript-Client in der Lage ist, den JSON-String umgehend in ein Array mehrerer JavaScript-Objekte zu konvertieren, die im weiteren Programmverlauf unmittelbar ausgewertet werden können.

Das folgende Beispiel zeigt, wie JavaScript-Code in einer HTML-Seite wirken kann.


<html>
<head>
  <script language="javascript" type="text/javascript">
// <!CDATA[
  var myarray= [{"id":"1","name":"Holzflos","vorname":"Hugo"},
  // ... Array wie oben ...
  {"id":"14","name":"Leinenlos","vorname":"Liane"}];
  function Button1_onclick() {
   try {
    for (var i = 0; i < myarray.length; i++) {
     var r = myarray[i];
     document.writeln("Mensch: " 
                      + r.vorname 
                      + " " 
                      + r.name 
                      + "<br/>");
    }
    // nehme eines der Obekte aus dem Array
    var obj3 = myarray[2];
    document.writeln("obj3: " 
                     + obj3.vorname 
                     + " " 
                     + obj3.name 
                     + "<br/>");
    // hier werden die Felder von obj3 überschrieben
    obj3.vorname="Resi";
    obj3.name="Denzschlos";
    document.writeln("obj3: " 
                     + obj3.vorname 
                     + " " 
                     + obj3.name 
                     + "<br/>");
    }
    catch (e) {
     document.writeln("Fehler: " + e);
   }
   return true;
  }
// ]]>
  </script>
</head>
<body>
  <p>
    <input  id="Button1" 
            type="button" 
            value="click here" 
            onclick="return Button1_onclick()"
     />
  </p>
</body>
</html>

Bitte beachten Sie, dass in der Zeile "var obj3 = myarray[2];" ein Objekt aus dem Array gewählt wird, dessen Felder in den folgenden Zeilen neu zugewiesen werden. Das ist bemerkenswert, weil das nicht in allen Programmiersprachen so einfach möglich ist.


obj3.vorname="Resi";
obj3.name="Denzschlos";

Die Ausgabe im Browser sieht so aus:


Mensch: Hugo Holzflos
Mensch: Stefan Sagblos
Mensch: Rudi Rhodos
Mensch: Karl Kolos
Mensch: Ludwig Lustlos
Mensch: Rita Ruhelos
Mensch: Susi Schlaflos
Mensch: Lotte Rielos
Mensch: Martin Muehelos
Mensch: Liane Leinenlos
obj3: Rudi Rhodos
obj3: Resi Denzschlos

JSON-Auswertung mit JavaScript in XSL

Neben den neueren Standard-Verfahren , und bieten spezielle Prozessoren auch die Möglichkeit, JavaScript direkt zu verarbeiten und damit auf JSON zuzugreifen.


<xsl:stylesheet version="1.0" 
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
     xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
     xmlns:jscript="http://jscript.org">
<xsl:output 
     method="xml" 
     omit-xml-declaration="yes" 
     indent="yes" 
     exclude-result-prefixes="msxsl jscript"/>
<msxsl:script 
       language="JavaScript" 
       implements-prefix="jscript">
<![CDATA[
var vjson=[ 
            {"NN":"Rielos", "VN":"Lotte"}, 
            {"NN":"Holzflos", "VN":"Hugo"}, 
            {"NN":"Denzschlos", "VN":"Resi"}
          ];
public function getJSONasString()
{
  // Deklariere eine Stringvariable 
  var verg="";
  // Schleife über alle Objekte im Array
  for(var i=0; i<vjson.length; i++){
      // nimm jeweils aktuelles Objekt aus dem Array
      var vobj = vjson[i];
      // verkette Informationen aus vobj
      // in die Stringvariable verg
      verg = verg + vobj.VN + " " + vobj.NN ;
      // Falls noch weitere Objekte kommen,
      // verkette verg mit "|"
      if(i<vjson.length-1) verg = verg + "|";
  }
  return verg;
}
]]>
</msxsl:script>
  <xsl:template match="/">  
  <root>  
  <xsl:value-of select="jscript:getJSONasString()"/>
  </root>
  </xsl:template>
</xsl:stylesheet>

Das generierte XML-Dokument sieht dann folgendermaßen aus:


<root>Lotte Rielos|Hugo Holzflos|Resi Denzschlos</root>

Die beschriebene Funktion getJSONasString zeigt, dass der Entwickler auch hier um ein klares Verständnis des jeweiligen Objekts nicht herumkommt. Um JSON auswerten zu können, muss bekannt sein, welche Properties ein Objekt hat.

In Java gibt es eine ganze Anzahl spezieller Klassen, die JSON-Strings in Java-Objekte deserialisieren können. Begriffe wie GSON oder JACKSON machen hier die Runde.

wg / 1. Mai 2019



Fragen? Anmerkungen? Tipps?

Bitte nehmen Sie Kontakt zu mir auf.






Vielen Dank für Ihr Interesse an meiner Arbeit.


V.i.S.d.P.: Wilfried Grupe * Klus 6 * 37643 Negenborn

☎ 0151. 750 360 61 * eMail: info10@wilfried-grupe.de

www.wilfried-grupe.de/JSON.html