XSLT: mit ESXLT eigenen Baum aufbauen

Teilweise möchte man in einem XSLT-Stylesheet Daten aus mehreren Quellen zusammenfügen, normalisieren und dann gemeinsam weiterverarbeiten. Dazu kann man sich eine Hilfsvariable aufbauen.

Hier ein Muster-XSLT, welches die Logik aufzeigt und nachfolgend noch genauer erklärt wird. Dieses Beispiel wurde vereinfacht und würde den Umweg über eine EXSL Variable nicht benötigen.

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl" xsl:version="1.0" xmlns:exsl="http://exslt.org/common" extension-element-prefixes="exsl">

<xsl:variable name="testvariable">
  <item>
    <title>Test 1</title>
    <sort>9</sort>
  </item>
  <item>
    <title>Test 2</title>
    <sort>8</sort>
  </item>
  <item>
    <title>Test 3</title>
    <sort>7</sort>
  </item>
  <item>
    <title>Test 4</title>
    <sort>6</sort>
  </item>
  <item>
    <title>Test 5</title>
    <sort>5</sort>
  </item>
</xsl:variable>

<xsl:variable name="mainRoot" select="/" />

<xsl:for-each select="exsl:node-set($testvariable)/item">
  <xsl:sort select="number(sort)" data-type="number" order="asccending" />
  <xsl:value-of select="title" />
  <xsl:text> </xsl:text>
  <xsl:value-of select="$mainRoot/data/test123" />
</xsl:for-each>

</root>

Im root-Tag (Zeile 1) muss EXSLT aktiviert werden. Im Standard XML-Parser von PHP ist dies bereits enthalten und benötigt keine weiteren Module oder dergleichen.

Danach definiert man sich eine Variable mit dem konsolidierten XML-Baum (Zeilen 4-25). Innerhalb der Variable sind for-each, auch auf externe Dokumente erlaubt, d.h. man kann sich so aus mehreren Quellen Daten anziehen und normalisiert in der gewünschten Struktur ablegen. Alle Tags (item, title, sort) sind natürlich beliebig definierbar.

Im späteren xsl:for-each ist das Root-Tag die Variable. Es ist deshalb empfehlenswert, das ursprüngliche Root-Element in eine Variable zu sichern, damit weiterhin auf diese Daten zugegriffen werden kann (Zeile 27)

Das eigentliche xsl:for-each auf Zeile 29 selektiert dann die Testvariable und geht durch jedes item-Element. Hier sind beliebige XPath Ausdrücke möglich. Dieses Element kann nun beliebig sortiert werden (Zeile 30), so kann man die verschiedenen Datenquellen mischen.

Diese Daten kann man dann beliebig ausgeben. "title" bezieht sich dabei relativ auf das "item", aber auch "/" wäre die Variable, count(/item) würde also 5 ausgeben. Möchte man auf ein Element des primären XMLs zugreifen benötigt es die zuvor definierte Variable für das mainRoot (Zeile 33)