XML Basics / XML: Processing-Instruction

XML: Processing-Instruction

XML: Processing-Instruction

Anweisungen zur Processing-Instruction helfen, XML-Dokumente mit temporären Zusatzinformationen zu versehen, die für die Weiterverarbeitung wichtig sind, ohne selbst Teil des XML-Dokuments zu sein. Beispielhaft sind hier browserseitige Transformationen von XML und XSL bzw. CSS.

XML: Processing-Instruction

Speziell bei komplexen XML-Konvertierungsstrecken ist es oft erforderlich, XML-Dokumente mit temporären Zusatzinformationen zu versehen, die bei der Weiterverarbeitung benötigt werden, z.B. Headerinformationen, Verweise und Bezüge zu anderen Dokumenten, Empfängeradressen u.v.a.m., die aber nicht Bestandteile des XML Dokuments werden sollen.

Da das XML Dokument selbst inhaltlich nicht verändert werden darf (Dokumentschutz) oder bei der XML Schema-Validierung ggf. auf einen Fehler laufen würde, behilft man sich oft damit, die Zusatzinformationen vor den Root-Node zu setzen. Dadurch verliert das XML-Dokument seine Wohlgeformtheit.

Im weiteren Konvertierungsprozeß müssen daher jene Zusatzinformationen erst wieder entfernt werden, damit das XML Dokument wieder wohlgeformt und valide ist und regulär verarbeitet werden kann.

Processing-Instructions machen diese Datenschnippelei durch externe Programme überflüssig. Mit ganz legalen Mitteln können einem XML Dokument Zusatzinformationen mitgegeben und später ausgelesen werden, ohne das Dokument wiederholt verändern und die Wohlgeformtheit gefährden zu müssen.


<xsl:processing-instruction 
  name="receiver">info10@wilfried-grupe.de</xsl:processing-instruction>

erzeugt folgenden Aufruf:


<?receiver info10@wilfried-grupe.de?>

PI's gehören selbst nicht zum XML Dokument. Auch wenn sie optisch ähnlich aussehen mögen wie Attribute oder Prologe, so haben sie damit nichts zu tun. XML Prozessoren ignorieren die PI's und leiten den Inhalt weiter. Um die PI's in XSLT wieder auslesen zu können, kann der Nodetest processing-instruction() verwendet werden.


<?receiver info10@wilfried-grupe.de?> <Books/> 

Die Auswertung der PI ist in XSLT dann ganz einfach:


<xsl:value-of 
     select="/processing-instruction('receiver')"/>

Der Output ist dann


info10@wilfried-grupe.de

Processing-Instructions sind in der XML Specification https://www.w3.org/TR/REC-xml/#sec-pi näher erläutert: "Processing instructions (PIs) allow documents to contain instructions for applications. ... PI's are not part of the document's character data, but MUST be passed through to the application."

Zahlreiche Anwendungen arbeiten mit diesem Konzept. Beeindruckend finde ich die Umsetzung in den XSLTForms, die clientseitig XForms mit XSLT kombinieren. Der Besuch von http://www.agencexml.com/xsltforms.htm, das Nachvollziehen der dort aufgeführten Beispiele sowie die ergänzenden Erläuterungen in https://en.wikibooks.org/wiki/Category:XSLTForms kann ich nur empfehlen.


<?xml-stylesheet href="xsltforms/xsltforms.xsl" type="text/xsl"?>
<?xsltforms-options debug="yes"?>

Verwendung finden die processing-instructions nicht zuletzt auch in der Verlagsbranche, etwa Zeitungsverlagen, wo bestimmte Platzhalter (Reiter, Dachzeile, Hauptzeile, Titel, Bildunterzeile, Quelle, Bildergalerie, Schlagwort, Vorspann, Autor) bereitgestellt werden, die im weiteren Konvertierungsverlauf verwendet werden. Eine Variante ist, diese Platzhalter durch Processing-instructions zu definieren, die im Input-Text an verschiedenen Stellen auftauchen können.

Einen Überblick über die verwendeten Processing-instructions eines XML Dokuments kann man durch folgendes XSL gewinnen:


<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" />
  <xsl:template match="/">
    <root>
      <xsl:for-each
        select="descendant::*/processing-instruction()">
        <pi>
          <xsl:value-of select="name()" />|<xsl:value-of select="." />
        </pi>
      </xsl:for-each>
    </root>
  </xsl:template>
</xsl:stylesheet>

Soll der Name der Processing-Instruction selbst zu einem Element im Zieldokument werden, andere Elemente jedoch erhalten bleiben, so empfiehlt sich folgender Ansatz:


  <xsl:template match="p | stichwort | foto-quelle">
    <xsl:element name="{name()}">
      <xsl:apply-templates />
    </xsl:element>
  </xsl:template>
  <xsl:template match="processing-instruction()">
    <xsl:element name="{name()}">
      <xsl:value-of select="."></xsl:value-of>
    </xsl:element>
  </xsl:template>
  <xsl:template match="/">
    <erg>
      <xsl:apply-templates />
    </erg>
  </xsl:template>

Browserseitige Transformation XML und XSL

Alternativ zur direkten Generierung von HTML ist es auch möglich, die XSL-Transformation im Webbrowser durchführen zu lassen. Das wird möglich, wenn das XML Dokument über die Einbindung von Processing-Instructions ein Hinweis auf das XSL-Dokument zugewiesen wird (hier z.B. unter dem Namen "HTMLTabelle.xsl"). Der Browser führt die XSL-Transformation durch und zeigt das XML-Dokument entsprechend modifiziert an.


<?xml-stylesheet 
    type="text/xsl" 
    href="HTMLTabelle.xsl" 
    version="1.0" 
    encoding="iso-8859-1"?>
<Orte>
  <Ort>
    <id>1</id>
    <name>Neustadt</name>
    <!-- weitere Inhalte -->
  </Ort>
</Orte>

Das funktioniert freilich nicht in jedem Browser identisch. So habe ich das XML Dokument mit Hinweis auf das oben beschriebene XSL-Stylesheet (samt dem <xsl:template name="listimport">) in verschiedenen Browsern aufgerufen. Microsofts Internet Explorer (verschiedene Versionen) kam damit problemlos klar. Firefox führte die XSL-Transformation grundsätzlich zwar durch, jedoch ohne das Template "listimport" auszuführen.

Browserseitige Transformation XML und CSS

Ganz analog funktioniert der Browseraufruf bei der Kombination von XML und CSS. Durch die Processing-Instruction wird ein externes CSS-Dokument eingebunden, der Browser stellt das XML-Dokument nun entsprechend dar.


<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet 
      type="text/css" 
      href="Abfrageergebnis.css" ?>
<ROOT>
  <DS nr="1">
    <ID>5</ID>
    <Vorname>Willi</Vorname>
    <Nachname>Wasistlos</Nachname>
    <Wohnort>Kapstadt</Wohnort>
    <Artikel>Hemd</Artikel>
    <anzahl>44</anzahl>
    <EP>12,99</EP>
    <NETTO>571,56</NETTO>
  </DS>
  <DS nr="2">
    <ID>9</ID>
    <Vorname>Stefan</Vorname>
    <Nachname>Sprachlos</Nachname>
    <Wohnort>Neustadt</Wohnort>
    <Artikel>Hemd</Artikel>
    <anzahl>33</anzahl>
    <EP>12,99</EP>
    <NETTO>428,67</NETTO>
  </DS>
<ROOT>

pic/XML_CSS.jpg

Die dazu passende CSS-Datei lautet:


ROOT
 { position:absolute;
   top:45px;
   left:45px;
   background-color:#C0C0C0;
   padding:90px;
 }
DS
 { position:relative;
   display:block;
   width:600px;
   background-color:#FFFF80;
   color:#000000;
   font-family:Tahoma,Arial,Helvetica,sans-serif;
   font-size:12pt;
   padding:2px;
   vertical-align:top;
 }
ID,Vorname,Nachname
 { position:relative;
   width:70px;
 }
Wohnort
 { position:relative;
   color:#000FFF;
   width:360px;
 }
Artikel, anzahl, EP, NETTO
 { font-weight:bold;
   color:0000E0;
 }

wg / 30. Dezember 2017



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