fjh: Abarbeitung externer Dokumente möglich?

Beitrag lesen

Hallo Alex,

DTD C:\gruppe.dtd:
<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT GRUPPE (PERSON+)>
<!ELEMENT PERSON (VORNAME, NAME)>
<!ELEMENT VORNAME (#PCDATA)>
<!ELEMENT NAME (#PCDATA)>

Die DTD habe ich unten weggelassen, da sie für das Problem unerheblich ist.


Das Ausgangsdokument sollte so aussehen:
(die Elementknoten heißen anders und Vorname und Name werden vertauscht)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE TEAM SYSTEM "C:\team.dtd">
<TEAM>
<MEMBER>
  <SURNAME>Müller</SURNAME>
  <FIRSTNAME>Peter</FIRSTNAME>
</MEMBER>
<MEMBER>
  <SURNAME>Meyer</SURNAME>
  <FIRSTNAME>Daniel</FIRSTNAME>
</MEMBER>
<MEMBER>
  <SURNAME>Schneider</SURNAME>
  <FIRSTNAME>Stefan</FIRSTNAME>
</MEMBER>
<MEMBER>
  <SURNAME>Kaiser</SURNAME>
  <FIRSTNAME>Thomas</FIRSTNAME>
</MEMBER>
<MEMBER>
  <SURNAME>Schulz</SURNAME>
  <FIRSTNAME>Andreas</FIRSTNAME>
</MEMBER>
</TEAM>

Das soll wohl nicht das _Ausgangs_dokument, sondern das _Ergebnis_dokument sein - zusammengeführt aus den Inhalten der oberen beiden Ausgangsdokumente.

Das XSL - OHNE Zusammenführung - könnte so aussehen:
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <TEAM>
   <MEMBER>
    <xsl:for-each select="GRUPPE/PERSON/NAME">
     <SURNAME>
      <xsl:value-of select="."/>
     </SURNAME>
    </xsl:for-each>
    <xsl:for-each select="GRUPPE/PERSON/VORNAME">
     <FIRSTNAME>
      <xsl:value-of select="."/>
     </FIRSTNAME>
    </xsl:for-each>
   </MEMBER>
  </TEAM>
</xsl:template>
</xsl:stylesheet>

Das ist schonmal, auch ohne Zusmamenführung, nicht das adäquate Stylesheet.

OHNE Einbeziehung der zweiten Datei wäre ein Stylesheet, das die gewünschte Transformation ausführt, das folgende:

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="iso-8859-1" indent="yes"/>

<xsl:template match="/">
  <TEAM>
    xsl:apply-templates/
  </TEAM>
 </xsl:template>

<xsl:template match="PERSON">
   <MEMBER>
       <SURNAME>
         <xsl:value-of select="NAME"/>
       </SURNAME>
       <FIRSTNAME>
         <xsl:value-of select="VORNAME"/>
       </FIRSTNAME>
   </MEMBER>
 </xsl:template>

</xsl:stylesheet>

So, wie nun das zweite Dokument reinbekommen? Über die document()-Funktion. Ein kleines Problem dabei ist, dass die Elemente im zweiten Dokument die gleichen Namen haben wie im ersten Dokument. D.h.

<xsl:template match="PERSON">
   <MEMBER>
       <SURNAME>
         <xsl:value-of select="NAME"/>
       </SURNAME>
       <FIRSTNAME>
         <xsl:value-of select="VORNAME"/>
       </FIRSTNAME>
   </MEMBER>
   <xsl:apply-templates select="document('../xml/xsl43b.xml')/GRUPPE/PERSON"/>
 </xsl:template>

führt zu einer Endlosschleife.

Du musst den Aufruf also hochziehen in das Template für das Wurzelelement:

<xsl:template match="/">
  <TEAM>
    xsl:apply-templates/
    <xsl:apply-templates select="document('../xml/xsl43b.xml')/GRUPPE/PERSON"/>
  </TEAM>
 </xsl:template>

Das Stylesheet musst du natürlich mit dem ersten Dokument verknüpfen bzw. es auf das erste Dokument anwenden.

Gruß
Franz