C#.NET * C++ * JAVASCRIPT * PYTHON * DIVERSES
XML * XML-SCHEMA * XPATH * XSL * XSL-FO * SVG * XQUERY * XPROC * ANT



XML / CDATA

CDATA

CDATA

➪ Neben Standard-Kommentaren gibt es noch CDATA-Kommentare. CDATA-Kommentare beginnen mit <![CDATA[ und enden mit ]]>. 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.

Auf dieser Seite:

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 entziehen und so eine geforderte, eindeutige Strukturdefinition aushebeln. In diesem Fall steht zu vermuten, dass das XSD mit den aktuellen Anforderungen nicht überein stimmt.

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 Validierungsfehler 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ässt 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>

CDATA-Kommentare auswerten

Obwohl CDATA-Kommentare nicht geparst werden und Inhalte betreffen können, die einer XML-Schema-Validierung widersprechen, ist es dennoch möglich, jene Inhalte als XML auszuwerten.


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

Variablen wie vfeld können Sie mit der XPath-Funktion 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ß dies gelungen ist, sehen Sie hier:


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

Das klappt auch in XQuery


let $input := <Person 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:noNamespaceSchemaLocation="Person.xsd">
  <Vorname>Peter</Vorname>  
  <Nachname>Problemlos</Nachname>
  <info>&lt;wichtig&gt;
&lt;Beruf&gt;IT-ler&lt;/Beruf&gt;
&lt;Hobby&gt;XML&lt;/Hobby&gt;
&lt;Hobby&gt;XSD&lt;/Hobby&gt;
&lt;Hobby&gt;XSL&lt;/Hobby&gt;
&lt;Hobby&gt;XQuery&lt;/Hobby&gt;
&lt;Hobby&gt;XProc&lt;/Hobby&gt;
&lt;/wichtig&gt;</info>
</Person>

Die XQuery-Abfrage:


for $w in parse-xml($input//info/text())//Hobby return $w

Hier lautet das Ergebnis:


<Hobby>XML</Hobby>
<Hobby>XSD</Hobby>
<Hobby>XSL</Hobby>
<Hobby>XQuery</Hobby>
<Hobby>XProc</Hobby>

Bei strukturellen Änderungen in den CDATA-Sections ist es notwendig, die Verarbeitungslogik (XSL, XQuery) anzupassen. Es kann aber vorkommen, dass diese Anpassung unterbleibt oder verzögert vorgenommen wird. Dann droht hier ein Informationsverlust, der sehr teuer werden kann. Daher empfieht sich auch hier eine Validierung.

CDATA in Scripting-Dateien

Einen Einsatzbereich für CDATA-Kommentare finden Sie 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.2020</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>

CDATA in ANT-Dateien

Einen vergleichbaren Einsatzzweck findet der CDATA-Kommentar in ANT, wo mittels JavaScript mehrere ANT-Echoaufrufe generiert werden, die im Ergebnis das unten stehende 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

CDATA in output|xsl:output

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" />

wg / 24. September 2020



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/CDATA.html