XML Basics / XML Kommentare

XML Kommentare

XML Kommentare

In XML, XSLT, XML Schema und anderen Standards sind ergänzende Kommentare hilfreich, um die Wartung komplexer Anwendungen zu erleichtern. Neben Standard-Kommentaren stehetm auch CDATA-Kommentare bereit.

XML Kommentare

Ergänzende Kommentare können weitere Hilfestellung geben. Ein Standard XML Kommentar beginnt mit <!-- und endet mit -->.


<root>
   <!-- this is a comment, you are free to write down your CV -->
</root>

XML-Kommentare in XSL erzeugen

In XSL ist es angebracht, zum besseren Verständnis der Programmlogik lokale Kommentare einzubauen, die nicht im Ergebnisdokument erscheinen. Simmvolle Kommentare können die Wartung der Programme sehr erleichtern, daher sind sie unbedingt zu empfehlen. Wie in jedem XML-Dokument, gilt auch hier die Syntax "<!-- Kommentar -->".


<erg>
  <!-- dieser Kommentar gilt nur lokal in XSL, 
       wird nicht im Ergebnisdokument erscheinen -->
</erg>

Die Ausgabe im Ergebnisdokument lautet wie beabsichtigt ohne Kommentar:


<erg/>

Um im Ergebnisdokument einen Kommentar sichtbar zu machen, können wir mit "<xsl:comment>" arbeiten.


<erg>
  <xsl:comment>Dieser Kommentar wird im Ergebnis erscheinen</xsl:comment>
</erg>

Die Ausgabe im Ergebnisdokument lautet:


<erg>
  <!--Dieser Kommentar wird im Ergebnis erscheinen-->
</erg>

XML-Kommentare in XSL auswerten

Umgekehrt ist es auch möglich, mit Hilfe von XSLT die Kommentare in den Input-Dokumenten auszuwerten. Betrachten wir folgendes XML Input Dokument, das - abgesehen von einem "root"-Node - ausschließlich XML-Kommentare aufweist.


<root>
<!--Kommentar 1-->
<!--Kommentar 2-->
<!--Kommentar 3-->
<!--Kommentar 4-->
</root>

Nun soll versucht werden, diese Kommentare in XSLT auszuwerten. Das funktioniert recht einfach:


<xsl:stylesheet version="1.0" 
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
  <xsl:template match="/">
    <Kommentare>
      <xsl:for-each select="/root/comment()">
        <info>
          <xsl:value-of select="."/>
        </info>
      </xsl:for-each>
    </Kommentare>
  </xsl:template>
</xsl:stylesheet>

Das Ergebnis ist wenig überraschend:


<?xml version="1.0" encoding="UTF-8"?>
<Kommentare>
	<info>Kommentar 1</info>
	<info>Kommentar 2</info>
	<info>Kommentar 3</info>
	<info>Kommentar 4</info>
</Kommentare>

Das obige XSL-Stylesheet konzentriert sich jedoch nur auf jene Kommentare, die unmittelbar unterhalb des "root"-Elements stehen. In der Regel sieht die Datenstruktur jedoch etwas komplexer aus:


<root>
 <!--Kommentar 1-->
 <Ebenea>
  <ka>
   <!--Kommentar 2-->
  </ka>
  <Ebeneb>
   <kb>
    <!--Kommentar 3-->
   </kb>
   <Ebenec>
    <kc>
     <!--Kommentar 4-->
    </kc>
   </Ebenec>
  </Ebeneb>
 </Ebenea>
</root>

Möchten wir nun nicht nur sämtliche Kommentare auf unterschiedlichen Ebenen auslesen, sondern auch den XPath zu dieser Ebene wissen, so können wir uns hiermit behelfen:


<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
 <xsl:template match="/">
  <Kommentare>
   <xsl:for-each select="/*/descendant-or-self::*/comment()">
    <info>
     <xsl:attribute name="xpath">
      <xsl:for-each select="ancestor-or-self::*">
       <xsl:text>/</xsl:text>
       <xsl:value-of select="name()"/>
      </xsl:for-each>
     </xsl:attribute>
     <xsl:value-of select="."/>
    </info>
   </xsl:for-each>
  </Kommentare>
 </xsl:template> 
</xsl:stylesheet>

Das Ergebnis hilft uns weiter:


<Kommentare>
 <info 
    xpath="/root">Kommentar 1</info>
 <info 
    xpath="/root/Ebenea/ka">Kommentar 2</info>
 <info 
    xpath="/root/Ebenea/Ebeneb/kb">Kommentar 3</info>
 <info 
    xpath="/root/Ebenea/Ebeneb/Ebenec/kc">Kommentar 4</info>
</Kommentare>

CDATA in Scripting-Dateien

Neben Standard-Kommentaren gibt es noch CDATA-Kommentare. Im Unterschied zu den Parsed Character Data (PCDATA), die durch einen Parser verarbeitet werden, beinhalten CDATA-Kommentare Daten, die nicht geparst werden. CDATA-Kommentare erlauben beispielsweise, zusätzliche XML Elemente einzufügen, die im XML Schema nicht definiert sind. Durch CDATA wird es möglich, diese nicht-validen Inhhalte vor etwaiger Validierung gegen DTD oder XML Schema zu schützen.

Einen Einsatzbereich für CDATA-Kommentare finden wir beispielsweise in Windows Scripting-Dateien, die im Kern XML Dokumente darstellen, deren Scriptanteile jedoch über den Windows Script Host ausgeführt werden können.


<?xml version="1.0" encoding="ISO-8859-1"?>
<job id="T1">
    <comment>
        <c1>File: dosomething.wsf</c1>
        <c1>Author: Wilfried Grupe</c1>
        <c1>Datum: 01.01.2018</c1>
        <c1>Description: writes Hello</c1>
    </comment>
    <script language="VBScript">
<![CDATA[
sub dosomething
    wscript.echo "Hallo"
end sub
]]>
    </script>
    <script language="JScript">
<![CDATA[
try { 
    // calling vbscript from JScript:
    dosomething(); 
}
catch(e) { 
    // Exceptionhandling in case something is going wrong
    WScript.echo(e.description); 
}
]]>
    </script>
</job>

Einen vergleichbaren Einsatzzweck findet der CDATA-Kommentar in ANT, wo mittels Javascript mehrere ANT-Echoaufrufe generiert werden, die im Ergebnis das untenstehende Bild ergeben.


  <target name="jstest">
    <script language="javascript">
    <![CDATA[          
      for(var z=0; z<15;z++){
        var str="";        
        for(var s=0; s<48; s++) {
          if(    z===s || s+z===14 
            || s===17 || s===31  || s===33 
            || (z==14 && s > 33) 
            || (z < 8) &&(s===17+z || z+s===31 )){
            str = str + "#";
          }
          else str = str + " ";
        }      
        var ve = MYANTPROJECT.createTask("echo");
        ve.setMessage(str);
        ve.perform();
      }        
    ]]>
    </script>
  </target>

pic/jstest.png

In xsl:output kann definiert werden, welche Elemente in CDATA-Section dargestellt werden sollen:


<xsl:output method="xml" indent="yes" 
     cdata-section-elements="erg wert" />

CDATA-Sections und XML Schema-Validierung

Häufig validieren Datenempfänger ihre XML-Dokumente "sehr scharf" gegen ein XML Schema. Mitunter sind in den XML Dokumenten jedoch CDATA-Sections enthalten, die Inhalte "maskieren", einer XSD-Validierung entziehen und so eine geforderte, eindeutige Strukturdefinition aushebeln.

Es bleibt dem Developer überlassen, bei eventuellen strukturellen Änderungen in den CDATA-Sections die Verarbeitungslogik (XSL, XQuery) anzupassen. Es kann aber vorkommen, daß diese Anpassung unterbleibt oder verzögert vorgenommen wird. Dann droht hier ein Informationsverlust, der sehr teuer werden kann.

Hierzu möchte ich ein einfaches Beispiel geben. Das folgende XML Schema definiert ein Root-Element Person mit drei xs:string-Childnodes "Vorname", "Nachname" und "info".


<xs:schema 
  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
  attributeFormDefault="unqualified"
  elementFormDefault="unqualified" version="1.0" >
  <xs:element name="Person" type="PersonTYP"/>
  <xs:complexType name="PersonTYP">
    <xs:sequence>
      <xs:element ref="Vorname" />        
      <xs:element ref="Nachname" />
      <xs:element ref="info" />
    </xs:sequence>
  </xs:complexType>
  <xs:element name="Vorname" type="xs:string" />
  <xs:element name="Nachname" type="xs:string" />
  <xs:element name="info" type="xs:string" />
</xs:schema>

Das folgende XML Dokument übernimmt "Vorname" und "Nachname", weist der "info" aber einen zusätzlichen Childnode "Hobby" zu, das im XML Schema nicht vorgesehen ist; ihre Existenz im XML Dokument sollte daher zu einem Validierungs-Fehler führen.


<Person 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:noNamespaceSchemaLocation="Person.xsd">
  <Vorname>Vorname</Vorname>  
  <Nachname>Nachname</Nachname>
  <info><Hobby>XML</Hobby></info>
</Person>

Der Validierungsfehler läßt auch nicht auf sich warten:


Element 'info' ist Simple Type und 
darf daher keine Elementinformationselemente 
[untergeordnete Elemente] haben. 
Person.xml is not a valid XML document

Dagegen geht die CDATA-"Maskierung" glatt durch:


<Person 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:noNamespaceSchemaLocation="Person.xsd">
  <Vorname>Vorname</Vorname>  
  <Nachname>Nachname</Nachname>
  <info><![CDATA[ <Hobby>XML</Hobby>]]> </info>
</Person>

Alternativ denkbar wäre, die Daten ohne CDATA-Section als Text mit Entitäten einzubinden; auch hier würde eine Validierung gegen das vorher beschriebene XML Schema problemlos durchlaufen:


<Person 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:noNamespaceSchemaLocation="Person.xsd">
  <Vorname>Vorname</Vorname>  
  <Nachname>Nachname</Nachname>
  <info>&lt;Hobby&gt;XML&lt;/Hobby&gt;</info>
</Person>

In beiden Fällen stellen sich aus meiner Sicht einige Fragen:

parse-xml-fragment

Obwohl CDATA-Kommentare nicht geparst werden und Inhalte betreffen können, die einer XML Schema-Validierung widersprechen, ist es doch möglich, daß diese Inhalte von Belang sind. Die XPath-Funktion "parse-xml-fragment" erlaubt deren Auswertung.

CDATA-Kommentare beginnen mit <![CDATA[ und enden mit ]]>.


 <xsl:variable name="vfeld">
  <![CDATA[
  <root>
    <i>Straße2</i>
    <i>Strasse1</i>
    <i>Weg</i>
    <i>Straße1</i>
    <i>Strasse2</i>
    <i>Pfad</i>
    </root>
   ]]>
 </xsl:variable>

Variable wie "vfeld" können wir mit Hilfe der XPath-Funktion "parse-xml-fragment" in ein XML-Dokument überführen und dieses auswerten.


<ergebnis>
  <xsl:for-each 
       select="parse-xml-fragment($vfeld)/root/i">
    <wert>
     <xsl:value-of select="."/>
    </wert>
  </xsl:for-each>   
</ergebnis>

Daß dieses gelungen ist, sehen wir hier:


<ergebnis>
   <wert>Straße2</wert>
   <wert>Strasse1</wert>
   <wert>Weg</wert>
   <wert>Straße1</wert>
   <wert>Strasse2</wert>
   <wert>Pfad</wert>
</ergebnis>

wg / 1. Januar 2018



Fragen? Anmerkungen? Tips?

Bitte nehmen Sie Kontakt zu mir auf:

Vorname
Nachname
Mailadresse







Vielen Dank für Ihr Interesse an meiner Arbeit.


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

Mobil: 0151. 750 360 61 * eMail: info2018@wilfried-grupe.de

www.wilfried-grupe.de/Kommentare.html