Die Adressierung

Unter der Adressierung ist eine Formulierung zu verstehen, die es dem Prozessor erlaubt, Knoten oder Knotenmengen anzusteuern bzw. diese zu selektieren. Solche Adressierungen werden auch Lokalisierungspfade genannt und können in unterschiedlichen Erscheinungsformen auftreten:

  • in verkürzter oder ausführlicher Schreibweise,
  • als relative oder absolute Lokalisierungspfade.

Verkürzte oder ausführliche Schreibweise

Für die hier bereits genannten Knoten und Achsen existiert eine verkürzte und eine ausführliche Schreibweise. Beide Schreibweisen werden in der Praxis gemischt verwendet. Die verkürzte ist immer dann üblich, wenn es sich um sehr häufig angesteuerte Knoten der Achsen handelt, während die ausführliche bei den selteneren Knoten und Achsen üblich ist. In den folgenden Abschnitten wird die ausführliche Schreibweise dargestellt und dazu die verkürzte, wenn sie häufig verwendet wird.

Ein Beispiel in ausführlicher Notation:

/child::buch/child::autor/child::name/attribut::nachname

In verkürzter Notation:

/buch/autor/name/@nachname

In der verkürzten Notation wird auf die Achsenbezeichnung child:: verzichtet und der Attributknoten mit dem Zeichen @ bezeichnet. Hierzu in den späteren Beispielen mehr.

Ausführliche SchreibweiseVerkürzte Schreibweise
child:: "Default"-Achse,
kann weggelassen werden
attribute:: @
descendant-or-self::node()/ //
self::node() .
parent::node() ..

Tabelle: Ausführliche und verkürzte Schreibweisen von Knoten und Achsen

Relative und absolute Pfade

Es ist möglich, einen Lokalisierungspfad relativ oder absolut (vom Wurzelelement ausgehend) zu schreiben. Genau genommen gehen die absoluten Lokalisierungspfade vom Wurzelknoten aus – das ist der Knoten, der direkt oberhalb des Wurzelelements liegt. Würde man diese Unterscheidung nicht machen und lediglich vom Wurzelelement ausgehen, dann könnte man beispielsweise Prozessinstruktionen oder Kommentare, die außerhalb des Wurzelelements liegen, nicht adressieren können.
Die Lokalisierungspfade setzen sich aus mehreren Einzelschritten zusammen, die durch Schrägstriche voneinander getrennt werden.

Ein Beispiel:

/child::EUROPA/child::LAND/child::NAME

In diesem Fall handelt es sich um einen absoluten Pfad, der vom Wurzelknoten ausgeht. Der Wurzelknoten wird mit dem ersten Schrägstrich angegeben. Von dort aus wird das Wurzelelement <EUROPA> selektiert, welches ein Kindelement <LAND>, das wiederum ein Kindelement <NAME> haben muss, damit es zu einem Treffer kommt. Die Achsen werden unter Angabe des Namens gefolgt von zwei Doppelpunkten angegeben. Im Falle von child:: kann die Achsenangabe auch entfallen. Folglich ist der Pfad /EUROPA/LAND/NAME gleichwertig (in verkürzter Schreibweise). Relative Pfade hingegen benötigen einen Kontextknoten. Der Pfad wird relativ zu diesem Knoten ausgewertet:

Beispiel:

child::LAND/child::NAME

In diesem Beispiel kommt es nur zu einem Treffer, wenn der Kontextknoten ein Kindelement <LAND> hat, das wiederum ein Element <NAME> enthält. Die Beschreibung für relative Pfade ist hier unvollständig! Wir verweisen auf Spezial-Literatur zu XPath.

XPath-Beispiele im Kontext eines XSLT-Stylesheets

Unsere Übungsinstanz (Europa.xml):

<?xml version="1.0" encoding="UTF-8"?>
<EUROPA>
   <LAND>
      <NAME>Deutschland</NAME>
      <EINWOHNERZAHL EINHEIT="Millionen">82.4</EINWOHNERZAHL>
      <HAUPTSTADT>Berlin</HAUPTSTADT>
      <KFZ-KENNZEICHEN>D</KFZ-KENNZEICHEN>
      <TEL-VORWAHL>0049</TEL-VORWAHL>
   </LAND>
   <LAND>
      <NAME>Frankreich</NAME>
      <EINWOHNERZAHL EINHEIT="Millionen">58.5</EINWOHNERZAHL>
      <HAUPTSTADT>Paris</HAUPTSTADT>
      <KFZ-KENNZEICHEN>F</KFZ-KENNZEICHEN>
      <TEL-VORWAHL>0033</TEL-VORWAHL>
   </LAND>
   <LAND>
      <NAME>Spanien</NAME>
      <EINWOHNERZAHL EINHEIT="Millionen">39.4</EINWOHNERZAHL>
      <HAUPTSTADT>Madrid</HAUPTSTADT>
      <KFZ-KENNZEICHEN>E</KFZ-KENNZEICHEN>
      <TEL-VORWAHL>0034</TEL-VORWAHL>
   </LAND>
</EUROPA>

Es folgt ein XSLT-Beispiel mit XPath-Adressierungen:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:template match="/">                                                (1)
      <html>
         <title></title>
         <body>
            <h3>
              <xsl:apply-templates/>
            </h3>
         </body>
      </html>
   </xsl:template>
   <xsl:template match="EUROPA">                                           (2)                    
     <xsl:if test="LAND/NAME">                                             (2)
       TREFFER : /EUROPA/LAND/NAME
       <br/>
     </xsl:if>
     <xsl:if test="LAND/EINWOHNERZAHL">                                    (3)
       TREFFER : /EUROPA/LAND/EINWOHNERZAHL
       <br/>
     </xsl:if>
     <xsl:if test="LAND/HAUPTSTADT">                                       (4)        
       TREFFER : /EUROPA/LAND/HAUPTSTADT
       <br/>
     </xsl:if>
     <xsl:if test="child::EINWOHNERZAHL">                                  (5)
       TREFFER : /EUROPA/EINWOHNERZAHL
       <br/>
     </xsl:if>
     <xsl:if test="descendant::EINWOHNERZAHL">                             (6)
       TREFFER : /EUROPA/descendant::EINWOHNERZAHL
       <br/>
     </xsl:if>
     <xsl:if test="LAND/NAME/following-sibling::EINWOHNERZAHL">            (7)
       TREFFER : /EUROPA/LAND/NAME/following-sibling::EINWOHNERZAHL
       <br/><br/><br/><br/>
     </xsl:if>
     <xsl:if test="LAND/NAME/following-sibling::EINWOHNERZAHL/             (8)  
       parent::LAND/descendant::HAUPTSTADT">
       TREFFER : /EUROPA/LAND/NAME/following-sibling::EINWOHNERZAHL/
       parent::LAND/descendant::HAUPTSTADT
       <br/><br/><br/><br/>
     </xsl:if>
     <xsl:apply-templates/> 
   </xsl:template> 
   <xsl:template match="LAND">                                             (9)
     <xsl:if test="HAUPTSTADT"> TREFFER : /EUROPA/LAND/HAUPTSTADT          (9)
       <br/>
     </xsl:if> 
     <xsl:if test="parent::EUROPA"> TREFFER : /EUROPA/LAND/parent::EUROPA  (10)
       <br/>
     </xsl:if>
   </xsl:template>
</xsl:stylesheet>
 

(1) Das Zeichen / bezeichnet den Wurzelknoten.

(2) Das Element <xsl:template> bezieht sich auf das Wurzelelement <EUROPA>. Für die nun nachfolgenden <xsl:if>-Elemente des Templates ist dies der Kontextknoten. Das heißt, dass alle nun folgenden Lokalisierungspfade von diesem Ausgangspunkt ausgehen. Im ersten Beispiel also LAND/NAME. Da es ein Kindelement <LAND> von <EUROPA> gibt, das selbst ein Kindelement <NAME> hat, werden die Anweisungen, die sich innerhalb des <xsl:if>-Elements befinden, ausgeführt. Es erscheint in der Anzeige der absolute Pfad: /EUROPA/LAND/NAME.

(3) Ein weiteres Beispiel zur Demonstration der Position des Kontextknotens.

(4) Ein weiteres Beispiel zur Demonstration der Position des Kontextknotens.

(5) Hier erfolgt keine Ausgabe, weil es vom Kontextknoten <EUROPA> aus betrachtet kein Kindelement namens <EINWOHNERZAHL> gibt. Hier hätte es auch genügt, EINWOHNERZAHL zu schreiben, da nach der Konvention dieses stellvertretend für child::EINWOHNERZAHL stehen kann.

(6) Hier erfolgt wieder eine Ausgabe, da es einen descendant (Nachkommen) <EINWOHNERZAHL> von <EUROPA> aus gibt.

(7) An dieser Stelle sucht der Prozessor nach einem nachfolgenden Geschwisterelement (following-sibling::)<EINWOHNERZAHL> von <NAME>, das ebenfalls <LAND> als Elternelement hat. Da das Element <EINWOHNERZAHL> tatsächlich nach <NAME> steht, erfolgt die Ausgabe.

(8) Das hier gezeigte Suchmuster soll zeigen, dass die Komplexität beliebig zu erhöhen ist. Hier wird nach einem Element gesucht, das ein Kindelement mit dem Namen <LAND> vom Kontextknoten <EUROPA> ist. Dieses soll wiederum ein Kindelement <NAME> enthalten, welches ein nachfolgendes Geschwisterelement <EINWOHNERZAHL> hat. Bis hierher entspricht diese Abfrage der vorangegangenen und wir wissen, dass diese zutrifft. Das Element <EINWOHNERZAHL> soll nun als Elternelement das Element <LAND> haben, welches einen Nachfahren <HAUPTSTADT> haben soll. Wie in der Ausgabe zu sehen, treffen alle diese Voraussetzungen zu.

(9) Das neue Template sorgt an dieser Stelle dafür, dass der Kontextknoten ein anderer ist. Nun beziehen sich die Suchmuster innerhalb des Templates auf <LAND>. An dieser Stelle wird gefragt, ob das Element <LAND> ein Kindelement <HAUPTSTADT> hat.

(10) Hier wird nach einem Elternelement <EUROPA> des Kontextknotens <LAND> gesucht.

Wir erhalten nun folgendes Ergebnis:

<html>
<title></title>
<body>
   <h3> 
       TREFFER : /EUROPA/LAND/NAME                                            (2)
       <br/> 
       TREFFER : /EUROPA/LAND/EINWOHNERZAHL                                   (3)
       <br/>
       TREFFER : /EUROPA/LAND/HAUPTSTADT                                      (4)
       <br/> 
       TREFFER : /EUROPA/descendant::EINWOHNERZAHL                            (6)
       <br/> 
       TREFFER : /EUROPA/LAND/NAME/following-sibling::EINWOHNERZAHL           (7)
       <br/><br/><br/><br/> 
       TREFFER : /EUROPA/LAND/NAME/following-sibling::EINWOHNERZAHL/          (8)
       parent::LAND/descendant::HAUPTSTADT 
       <br/><br/><br/><br/> 
       TREFFER : /EUROPA/LAND/HAUPTSTADT                                      (9)
       <br/> 
       TREFFER : /EUROPA/LAND/parent::EUROPA                                  (10)
       <br/> 
       TREFFER : /EUROPA/LAND/HAUPTSTADT                                      (9)
       <br/> 
       TREFFER : /EUROPA/LAND/parent::EUROPA                                  (10)
       <br/> 
       TREFFER : /EUROPA/LAND/HAUPTSTADT                                      (9)
       <br/> 
       TREFFER : /EUROPA/LAND/parent::EUROPA                                  (10)
       <br/>
  </h3>
</body>
</html>

Browser-Ansicht

In bestimmten Satzgestaltungen (z.B. in diesem Buch) möchte man allgemein die erste Zeile eines Absatzes um einen bestimmten Wert einrücken, dies aber nicht nach direkt vorangehenden Überschriften, die am linken Satzspiegelrand angeschlagen sind. Das erste hier folgende Template regelt die Gestaltung für die Absätze allgemein, das zweite gilt für alle Absätze, die einer Überschrift direkt folgen. Das Absatzelement heißt <para>, das Überschriftenelement <title>.

<xsl:template match="para">
   <fo:block text-indent="6mm"><xsl:apply-templates/></fo:block>
</xsl:template>
<xsl:template match="para[preceding-sibling::*[1][self::title]]">
   <fo:block text-indent="0mm"><xsl:apply-templates/></fo:block>
</xsl:template>

Zur weiteren Einübung hier eine kleine Sammlung von Pfaden:

  • child::EUROPA gibt die Kindelemente vom Element <EUROPA> zurück.
  • child::node() gibt die Kindknoten des Kontextknotens zurück.
  • attribute::EINHEIT ist die ausgeschriebene Schreibweise für das gebräuchliche @EINHEIT und gibt den Inhalt des Attributs EINHEIT des Kontextknotens zurück.
  • descendant::EUROPA gibt die Abkömmlinge vom Element <EUROPA> zurück.
  • self::EUROPA gibt sich zurück, falls der Kontextknoten gerade das Element <EUROPA> ist.
  • / gibt das Wurzelelement zurück.
  • //*/@* gibt beliebige Attribute eines beliebigen Elements zurück.
  • /child::comment() gibt alle Kommentarknoten zurück, die Kinder des Wurzelknotens sind.

Adressierung verschiedener Knotentypen

Bisher haben wir uns sehr stark auf die Adressierung von Elementknoten konzentriert. Neben Elementen können aber auch alle anderen Kontentypen selektiert und zur Auswertung und weiteren Verarbeitung und Ausgabe herangezogen werden. Die nachfolgende Tabelle mit Beispieln zeigt die Möglichkeiten, diese Knontenselektion vorzunehmen.

name/text() Soll der Textknoten des Elements name angesprochen werden, geschieht dies durch den Knotentest text().
adresse/comment() Soll der Kommentarknoten des Elements adresse angesprochen werden, geschieht dies durch den Knotentest comment().
ort/processing-instruction() Soll der PI-Knoten des Elemente ort angesprochen werden, geschieht dies durch den Knotentest processing-instruction().
adresse/node() Sollen alle Knotentypen (außer Attribute) angesprochen werden, geschieht dies durch den Knotentest node().
<< zurück vor >>
Tipp der data2type-Redaktion:
Zum Thema XPath bieten wir auch folgende Schulungen zur Vertiefung und professionellen Fortbildung an:

Copyright © dpunkt.verlag GmbH 2007
Für Ihren privaten Gebrauch dürfen Sie die Online-Version ausdrucken. Ansonsten unterliegt dieses Kapitel aus dem Buch "Professionelle XML-Verarbeitung mit Word" denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

dpunkt.verlag GmbH, Ringstraße 19B, 69115 Heidelberg, fon 06221-14830, fax 06221-148399, hallo(at)dpunkt.de