Attribute in Elemente umwandeln

(Auszug aus "XSLT Kochbuch" von Sal Mangano)

Problem

Sie haben ein Dokument, das Informationen mit Attributen kodiert, und würden stattdessen lieber Kindelemente verwenden.

Lösung

XSLT 1.0

Dieses Problem ist wie maßgeschneidert für den in der Einleitung dieses Kapitels erwähnten überschreibenden Kopiervorgang. Dieses Beispiel transformiert global Attribute in Elemente:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:import href="copy.xslt"/>
  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
  <xsl:template match="@*">
    <xsl:element name="{local-name(.)}" namespace="{namespace-uri(..)}">
      <xsl:value-of select="."/>
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

Das Stylesheet funktioniert, indem das Kopierverhalten für Attribute außer Kraft gesetzt wird. Es ersetzt das Verhalten durch ein Template, das ein Attribut in ein Element (desselben Namens) umwandelt, dessen Inhalt der Wert des Attributs ist. Es nimmt außerdem an, dass dieses neue Element im gleichen Namensraum liegen soll wie das Elternelement des Attributs. Falls Sie es vorziehen, keine Annahmen zu treffen, verwenden Sie den folgenden Code:

<xsl:template match="@*">
  <xsl:variable name="namespace">
    <xsl:choose>
      <!--Verwendet den Namensraum des Attributs, falls es einen gibt -->
      <xsl:when test="namespace-uri( )">
        <xsl:value-of select="namespace-uri( )" />
      </xsl:when>
      <!--Ansonsten wird der Namensraum des Elternelements verwendet -->
      <xsl:otherwise>
        <xsl:value-of select="namespace-uri(..)" />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>
  <xsl:element name="{name( )}" namespace="{$namespace}">
    <xsl:value-of select="." />
  </xsl:element>
</xsl:template>

Oft werden Sie wählerisch sein wollen, wenn Sie Attribute in Elemente umwandeln (siehe die drei folgenden Beispiele).

Beispiel: Eingabe.

<people which="MeAndMyFriends">
  <person firstname="Sal" lastname="Mangano" age="38" height="5.75"/>
  <person firstname="Mike" lastname="Palmieri" age="28" height="5.10"/>
  <person firstname="Vito" lastname="Palmieri" age="38" height="6.0"/>
  <person firstname="Vinny" lastname="Mari" age="37" height="5.8"/>
</people>

Beispiel: Ein Stylesheet, das nur person-Attribute transformiert.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:import href="copy.xslt"/>
  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
  <xsl:template match="person/@*">
    <xsl:element name="{local-name(.)}" namespace="{namespace-uri(..)}">
      <xsl:value-of select="."/>
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

Beispiel: Ausgabe.

<people which="MeAndMyFriends">
  <person>
    <firstname>Sal</firstname>
    <lastname>Mangano</lastname>
    <age>38</age>
    <height>5.75</height>
  </person>
  <person>
    <firstname>Mike</firstname>
    <lastname>Palmieri</lastname>
    <age>28</age>
    <height>5.10</height>
  </person>
  <person>
    <firstname>Vito</firstname>
    <lastname>Palmieri</lastname>
    <age>38</age>
    <height>6.0</height>
  </person>
  <person>
    <firstname>Vinny</firstname>
    <lastname>Mari</lastname>
    <age>37</age>
    <height>5.8</height>
  </person>
</people>

XSLT 2.0

In XSLT 2.0 kann die Lösung noch rationeller gestaltet werden, das Rezept bleibt jedoch prinzipiell gleich. Hier können Sie das umständliche xsl:choose durch einen if-Ausdruck aus XPath 2.0 ersetzen.

<xsl:template match="@*">
  <xsl:variable name="namespace" select="if (namespace-uri( )) then namespace-uri( ) else namespace-uri(..)"/>
  <xsl:element name="{name( )}" namespace="{$namespace}">
    <xsl:value-of select="." />
  </xsl:element>
</xsl:template>

Diskussion

Dieses sowie das folgende Rezept behandeln die Probleme, die auftreten, wenn derjenige, der ein Dokument entworfen hat, eine ungünstige Entscheidung bezüglich der Kodierung von Informationen in Attributen oder in Elementen getroffen hat. Die Entscheidung »Attribut oder Element« gehört zu den umstrittensten Aspekten des Dokumentenentwurfs. (Anmerkung: Der einzige andere stilistische Streitpunkt, bei dem Softwareentwickler nach meiner Erfahrung noch stärker in Wallung geraten, ist die Frage, wo in C-artigen Programmiersprachen, z.B. C++ und Java, die geschweiften Klammern gesetzt werden müssen.) Diese Beispiele sind hilfreich, weil sie es Ihnen erlauben, Ihre Fehler oder die Fehler anderer zu korrigieren.

  

<< zurück vor >>

 

 

 

Tipp der data2type-Redaktion:
Zum Thema XSLT bieten wir auch folgende Schulungen zur Vertiefung und professionellen Fortbildung an:

Copyright © 2006 O'Reilly Verlag GmbH & Co. KG
Für Ihren privaten Gebrauch dürfen Sie die Online-Version ausdrucken.
Ansonsten unterliegt dieses Kapitel aus dem Buch "XSLT Kochbuch" 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.

O'Reilly Verlag GmbH & Co. KG, Balthasarstraße 81, 50670 Köln, kommentar(at)oreilly.de