Home
Über mich
Blog
Veröffentlichungen
IT-Trainings
Impressum


xsl:apply-templates: Teilkonvertierung des XML-Input

xsl:apply-templates: Teilkonvertierung des XML-Input

Manchmal stehen wir vor der Aufgabe, aus einem komplexen XML-Inputdokument nur eine Teilstruktur verändern zu müssen. Dabei erscheint es überflüssig, das gesamte Mapping zu implementieren.

Nehmen wir an, das folgende Dokument soll weitgehend unverändert gelassen, lediglich die "Kauf"-Elemente sollen von der Element- in die Attributschreibweise überführt und mit einem neuen Namespace versehen werden. Auch das Root-Element ist entsprechend anzupassen.

  <ROOT>
    <Ort>
      <id>1</id>
      <name>Neustadt</name>
    </Ort>
    <Mensch>
      <id>1</id>
      <name>Holzflos</name>
      <vorname>Hugo</vorname>
      <Gehalt>234.56</Gehalt>
      <idOrt>1</idOrt>
    </Mensch>
    <Kauf>
      <id>1</id>
      <anzahl>3</anzahl>
      <idMensch>1</idMensch>
      <idWare>1</idWare>
    </Kauf>
    <Kauf>
      <id>1</id>
      <anzahl>6</anzahl>
      <idMensch>1</idMensch>
      <idWare>1</idWare>
    </Kauf>
    <Ware>
      <id>1</id>
      <bez>Hemd</bez>
      <preis>12.99</preis>
    </Ware>
  </ROOT>

Die Umsetzung ist beispielsweise in der Form möglich, daß eine Schleife sämtliche Childnodes des Rootelements durchläuft und via xsl:apply-templates jeweils ein passendes Template aufruft.

<xsl:stylesheet version="2.0" 
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
     xmlns:z="www.neuezielstruktur.de">
  <xsl:output method="xml" 
       version="1.0" 
       encoding="UTF-8" 
       indent="yes"/>
  <xsl:template match="/">
    <z:NEUESROOT>
      <xsl:for-each select="/ROOT/child::*">
        <xsl:apply-templates select="."/>
      </xsl:for-each>
    </z:NEUESROOT>
  </xsl:template>

Das <xsl:template match="Kauf"> übernimmt die gewünschten Änderungen:

  <xsl:template match="Kauf">
    <z:k>
      <xsl:for-each select="child::*">
        <xsl:attribute name="{local-name()}" select="."/>
      </xsl:for-each>
    </z:k>
  </xsl:template>

Die restlichen Childnodes des ursprünglichen XML-Input-ROOT-Nodes werden über ein allgemeines Template, das alle weiteren Elemente anspricht, übernommen. Gegebenenfalls wäre eine Implementierung auch über xsl:copy-of oder ein weiteres xsl:apply-templates sinnvoll.

Bei derlei pauschalen Aufrufen ist jedoch besondere Vorsicht und sorgfältiges Testing notwendig, um sicherzustellen, daß keine unerwünschten Effekte auftreten.

  <xsl:template match="*">
    <xsl:element name="{name()}">
      <xsl:for-each select="child::*">
        <xsl:element name="{local-name()}">
          <xsl:value-of select="."/>
        </xsl:element>
      </xsl:for-each>
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

Das Ergebnis ist jedenfalls vorerst nach Wunsch:

<z:NEUESROOT xmlns:z="www.neuezielstruktur.de">
  <Ort>
    <id>1</id>
    <name>Neustadt</name>
  </Ort>
  <Mensch>
    <id>1</id>
    <name>Holzflos</name>
    <vorname>Hugo</vorname>
    <Gehalt>234.56</Gehalt>
    <idOrt>1</idOrt>
  </Mensch>
  <z:k id="1" anzahl="3" idMensch="1" idWare="1"/>
  <z:k id="1" anzahl="6" idMensch="1" idWare="1"/>
  <Ware>
    <id>1</id>
    <bez>Hemd</bez>
    <preis>12.99</preis>
  </Ware>
</z:NEUESROOT>

qrpic/applytemplates_neue_Teilstruktur.jpg

wg / 18. September 2017




Fragen? Anmerkungen? Tips?

Bitte nehmen Sie Kontakt zu mir auf (info10@wilfried-grupe.de).



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: info10@wilfried-grupe.de