Kerstin: XML aus XSL heraus aufrufen

Hallo,

ich hatte vor kurzem hier schon einen Beitrag geschrieben
(http://forum.de.selfhtml.org/archiv/2006/3/t124779/#m804179). Allerdings ist dieser schon im Archiv gelandet. Habe aber dazu noch eine Frage.
Wie dort schon beschrieben, habe ich eine XML-Datei mit den Daten und eine andere Datei mit der Darstellung. Die Ersetzung von <cdliste/> soll nun aber in einer weiteren XML-Datei hinterlegt werden:
cdcatalog_liste.xml
<tr>
 <td><title/></td>
 <td><artist/></td>
</tr>

So dass, an dieser Stelle im cdcatalog.xsl nur
 <xsl:template match="cd_liste">
  <xsl:for-each select="document('cdcatalog_data.xml')/catalog/cd">
   //Aufruf cdcatalog_liste.xml -> Kopieren der Elemente und ersetzen
   //von <title/> und <artist/>
  </xsl:for-each>
 </xsl:template>

Ich habe schon probiert, das ganze in einer separaten xsl-Datei unterzubringen und diese dann in die Haupt-XSL-Datei zu importieren. Allerdings werden die Daten da überhaupt nicht ersetzt oder gar die kopierten Elemente angezeigt. Dies wäre natürlich die beste Lösung, wenn sowas ausgelagert und einfach durch ein <xsl:import .../> eingefügt werden könnte.

Im Moment weiß ich keine Rat und ob das überhaupt geht.

Gruß,
Kerstin

  1. Hallo,

    Ich habe schon probiert, das ganze in einer separaten xsl-Datei unterzubringen und diese dann in die Haupt-XSL-Datei zu importieren. [...] ausgelagert und einfach durch ein <xsl:import .../>

    Hast du es mit xsl:include schon versucht?

    Bei xsl:import bezogen sich Referenzen (d.h. der basis URL z.B. im document()-Funktion) auf das XSL, das importiert wurde. Heisst, ein document('abc.xml') wird im selben Verzeichniss gesucht in dem das XSL steht, dass diese Funktion enthält.
    Außerdem ist es in deinem Fall notwendig xsl:apply-imports zu verwenden.

    Grüße
    Thomas

    1. Hallo Thomas,

      mit <xsl:import href=".." /> klappts ganz gut. Mit <xsl:include .../> gar nicht. Aber das xsl:apply-imports/ an der richtigen Stelle bringt schon einige Resultat :-) Vielen Dank. Allerdings werden die gewünschten Tags im 2. XSL nicht ersetzt ...

      1. XSL: cdcatalog.xsl
      <xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:import href="cdcatalog_liste.xsl"/> [1]
       <xsl:template match="/">
        <xsl:apply-templates />
       </xsl:template>
       <xsl:template match="*[name() != 'cd_liste']">
        xsl:copy
         <xsl:for-each select="@*">
         <xsl:copy />
        </xsl:for-each>
          <xsl:apply-templates />
        </xsl:copy>
       </xsl:template>
       <xsl:template match="cd_liste">
        <xsl:for-each select="document('cdcatalog.xml')/catalog/cd">
          <xsl:variable name="title">[2]
            <xsl:value-of select="title"/>
          </xsl:variable>
          <xsl:variable name="artist">
           <xsl:value-of select="artist"/>
          </xsl:variable>
          <xsl:for-each select="document('cdcatalog_liste.xml')">[3]
           xsl:apply-imports/[4]
          </xsl:for-each>
        </xsl:for-each>
       </xsl:template>
      </xsl:stylesheet>

      Bei [1] wird das 2. XSL importiert. Bei [2] hole ich mir aus der XML-Datei mit den Daten 'cdcatalog.xml' die gewünschten Daten und "speichere" diese jeweils in eine Variable. Außerdem soll ja für jede vorkommende CD eine Zeile in der Tabelle erstellt werden. Die Struktur der Tabelle liegt in cdcatalog_liste.xml ([3]). Mit xsl:apply-imports/ bei [4] wird nun auch das 2. XSL aufgerufen:

      2. XSL: cdcatalog_liste.xsl
      <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
      <xsl:template match="/">
       <xsl:apply-templates />
      </xsl:template>
       <xsl:template match="*[name() != 'title' and name() != 'artist']">
        xsl:copy
         <xsl:for-each select="@*">
         <xsl:copy />
        </xsl:for-each>
          <xsl:apply-templates />
        </xsl:copy>
       </xsl:template>
       <xsl:template match="title">
          <xsl:value-of select="$title"/>
       </xsl:template>
       <xsl:template match="artist">
          <xsl:value-of select="$artist"/>
       </xsl:template>
      </xsl:stylesheet>

      Allerdings wird alles kopiert, auch <title> und <artist> und nicht durch die Variabelen ersetzt. So, dass mein HTML-Output so aussieht:
      <html>
      <body>
       <h2>My CD Collection</h2>
          <table border="1">
            <tr bgcolor="#9acd32">
              <th align="left">Title</th>
              <th align="left">Artist</th>
            </tr>
            <tr>
          <td><title></title></td>
          <td><artist></artist></td>
         </tr>
      <tr>
          <td><title></title></td>
          <td><artist></artist></td>
         </tr>
      <tr>
          <td><title></title></td>
          <td><artist></artist></td>
         </tr>
      </table>
      </body>
      </html>

      Das heißt für mich, ich bin auf dem richtigen Weg. Nur die Ersetzung geht nicht richtig ... Jemand einen Tipp für mich?

      Gruß,
      Kerstin

      1. Hallo,

        kannst du noch ein Beispiel-XML posten?

        <xsl:for-each select="document('cdcatalog_liste.xml')">[3]
           xsl:apply-imports/[4]
        </xsl:for-each>

        Bezieht sich auf den Wurzelknoten vom "cdcatalog_liste.xml", aber im
        2. XSL: cdcatalog_liste.xsl bringt dir das
        <xsl:template match="/">
         <xsl:apply-templates />
        </xsl:template>
        nichts.

        Mit einem:
        <xsl:for-each select="document('cdcatalog_liste.xml')/*">[3]
           xsl:apply-imports/
        </xsl:for-each>
        sollte es gehen.

        Ich würede auch aus:
        <xsl:variable name="title">[2]
            <xsl:value-of select="title"/>
        </xsl:variable>
        ein: <xsl:variable name="title" select="title" /> machen.

        Allerdings ich sehe keinen Vorteil in diese Auslagerung, im Gegenteil, so wie sie jetzt ist, finde ich sie unnötig, weil sie die Sachen komplizierter macht, statt sie zu vereinfachen. (natürlich kenne ich nicht dein gesamt XSL)

        Grüße
        Thomas

        1. Hallo,

          kannst du noch ein Beispiel-XML posten?

          sicher:
          1. XML mit den Daten: cdcatalog.xml
          <catalog>
           <cd>
            <title>Empire Burlesque</title>
            <artist>Bob Dylan</artist>
            <country>USA</country>
            <company>Columbia</company>
            <price>10.90</price>
            <year>1985</year>
           </cd>
           <cd>
            <title>Hide your heart</title>
            <artist>Bonnie Tyler</artist>
            <country>UK</country>
            <company>CBS Records</company>
            <price>9.90</price>
            <year>1988</year>
           </cd>
          </catalog>

          2. XML mit der obersten Struktur: cdcatalog_book.xml
          <html>
           <body>
           <h2>My CD Collection</h2>
              <table border="1">
                <tr bgcolor="#9acd32">
                  <th align="left">Title</th>
                  <th align="left">Artist</th>
                </tr>
                <cd_liste/>
              </table>
           </body>
          </html>
          worin <cdliste/> ersetzt werden soll

          3. XML mit Struktur der Listenstruktur: cdcatalog_liste.xml
          <tr>
              <td><title/></td>
              <td><artist/></td>
          </tr>

          Mit einem:
          <xsl:for-each select="document('cdcatalog_liste.xml')/*">[3]
             xsl:apply-imports/
          </xsl:for-each>
          sollte es gehen.

          Ging auch ohne. Mit ist kein Unterschied zu merken.

          Allerdings ich sehe keinen Vorteil in diese Auslagerung, im Gegenteil, so wie sie jetzt ist, finde ich sie unnötig, weil sie die Sachen komplizierter macht, statt sie zu vereinfachen. (natürlich kenne ich nicht dein gesamt XSL)

          Der Vorteil läge für mich darin, 1. die Anzeige-Struktur von den Daten getrennt zu halten. Die Anzeige-Struktur könnte nach belieben angepasst werden. Nur die Platzhalter für die Daten sollten erhalten bleiben, um die Daten einzufügen. 2. wäre damit auch die Wiederverwendbarkeit der Anzeige-Struktur möglich. Wenn an verschiedenen Stellen ein und die selbe Anzeigestruktur benötigt würde, bräuchte ich diese so nur einmal hinterlegen (cdcatalog_liste.xml) und rufe sie im HauptXSL nur jedesmal auf, kopiere die Elemente, die übernommen werden und ersetze die die durch Daten ersetzt werden sollen.

          Das HauptXSL cdcatalog.xsl sieht immer noch so aus wie ich es vorher gepostet hatte:
          <xsl:import href="cdcatalog_liste.xsl"/>

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

          <xsl:template match="*[name() != 'cd_liste']">
            xsl:copy
             <xsl:for-each select="@*">
             <xsl:copy />
            </xsl:for-each>
              <xsl:apply-templates />
            </xsl:copy>
           </xsl:template>

          <xsl:template match="cd_liste">
            <xsl:for-each select="document('cdcatalog.xml')/catalog/cd">
             <xsl:variable name="title" select="title"></xsl:variable>
             <xsl:variable name="artist" select="artist"></xsl:variable>
              <xsl:for-each select="document('cdcatalog_liste.xml')/*">
               xsl:apply-imports/
             </xsl:for-each>
            </xsl:for-each>
           </xsl:template>

          Mehr steht da echt noch nicht drin.

          Gruß,
          Kerstin

          1. Hallo,

            kannst du noch ein Beispiel-XML posten?

            sicher:

            Ehm ... na ja, genau das ist  - meine Meinung nach - falsch. Du versuchst Layout mit dem XML zu mischen und das auszulagern. Besser, weil logischer und besser wartbar, wäre das Layout in einem XSL-Template auszulagern.

            Mit einem:
            <xsl:for-each select="document('cdcatalog_liste.xml')/*">[3]
               xsl:apply-imports/
            </xsl:for-each>
            sollte es gehen.

            Ging auch ohne. Mit ist kein Unterschied zu merken.

            Mein Fehler. (Aber dein XSLT-Prozessor sollte auch meckern!)
            xsl:apply-imports/ kann nur innerhalb von xsl:template verwendet werden.
            Falls dir das etwas sagt: apply-import verhält sich analog zur  super()-Funktion im objektorientierten Programmierung.

            Weiters - auch mein Fehler, das übergesehen zu haben - in deinem zu importierenden XSL werden die Variablen zwar verwendet, aber nicht deklariert . (auch deshalb hätte dir eigentlich der Prozessor eine Fehlermelung liefern müssen)

            Der Vorteil läge für mich darin, 1. die Anzeige-Struktur von den Daten getrennt zu halten. Die Anzeige-Struktur könnte nach belieben angepasst werden.

            Das machst du abern icht in dem du XML mit dem Layout mischst. Das wäre _die_ aufgabe für dein XSLT.

            »»2. wäre damit auch die Wiederverwendbarkeit der Anzeige-Struktur möglich. Wenn an verschiedenen Stellen ein und die selbe Anzeigestruktur benötigt würde, bräuchte ich diese so nur einmal hinterlegen (cdcatalog_liste.xml) und rufe sie im HauptXSL nur jedesmal auf, kopiere die Elemente, die übernommen werden und ersetze die die durch Daten ersetzt werden sollen.

            Für solchen Zwecke verwendet man (benannte) Templates mit Parameters.
            Was du hier versuchst entzieht sich meiner Logik ;-)
            Du willst, aus einem importiertem XSL nicht nur (rückwärts) auf die Funktionen im aufrufenden XSL zurückgreifen, sondern auch noch auf ein XML, das du durch das aufrufende XSL bestimmt wird, zugrifen und darin Daten ersetzen, die wiederum in einem anderen, ebenfalls durch das aufrufende XSL bestimmten, XML enthalten sind.

            Ich habe keine Lösung dafür.

            Ich finde es auch wesentlihc übersichtlicher so (ohne "cdcatalog_liste.xml")
            <?xml version="1.0" encoding="iso-8859-1"?>
            <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
             <xsl:template match="/">
              <xsl:apply-templates />
             </xsl:template>

            <xsl:template match="*[name() != 'cd_liste']">
              xsl:copy
               <xsl:for-each select="@*">
                <xsl:copy />
               </xsl:for-each>
               <xsl:apply-templates />
              </xsl:copy>
             </xsl:template>

            <xsl:template match="cd_liste">
              <xsl:for-each select="document('cdcatalog.xml')/catalog/cd">
               <tr>
                <td><xsl:value-of select="title" /></td>
                <td><xsl:value-of select="artist" /></td>
               </tr>
              </xsl:for-each>
             </xsl:template>
            </xsl:stylesheet>

            Willst du unbedingt etwas auslagern, fände ich immer noch besser so (ebenfalls ohne "cdcatalog_liste.xml"):

            -------------------------------
            <?xml version="1.0" encoding="iso-8859-1"?>
            <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
             <xsl:include href="formatknoten.xsl" />
             <xsl:variable name="myXML" select="document('cdcatalog.xml')/catalog" />
             <xsl:template match="/">
              <xsl:apply-templates />
             </xsl:template>

            <xsl:template match="*[name() != 'cd_liste']">
              xsl:copy
               <xsl:for-each select="@*">
                <xsl:copy />
               </xsl:for-each>
               <xsl:apply-templates />
              </xsl:copy>
             </xsl:template>
             <xsl:template match="cd_liste">
              <xsl:call-template name="formatnode">
               <xsl:with-param name="node" select="." />
               <xsl:with-param name="documentNode" select="$myXML/cd" />
               <xsl:with-param name="documentElements" select="$myXML/cd/title | $myXML/cd/artist" />
               <xsl:with-param name="documentNodeElementName" select="'tr'" />
               <xsl:with-param name="documentElementsElementName" select="'td'" />
              </xsl:call-template>
             </xsl:template>
            </xsl:stylesheet>

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

            <xsl:template name="formatnode">
              <xsl:param name="node" />
              <xsl:param name="documentNode" />
              <xsl:param name="documentElements" />
              <xsl:param name="documentNodeElementName" />
              <xsl:param name="documentElementsElementName" />
              <xsl:for-each select="$node">
               <xsl:for-each select="$documentNode">
                <xsl:element name="{$documentNodeElementName}">
                 <xsl:for-each select="current()/*[. = $documentElements]">
                  <xsl:element name="{$documentElementsElementName}">
                   <xsl:value-of select="." />
                  </xsl:element>
                 </xsl:for-each>
                </xsl:element>
               </xsl:for-each>
              </xsl:for-each>
             </xsl:template>

            </xsl:stylesheet>
            -------------------------------

            Grüße
            Thomas

            1. Hallo,

              kannst du noch ein Beispiel-XML posten?

              sicher:

              Ehm ... na ja, genau das ist  - meine Meinung nach - falsch. Du versuchst Layout mit dem XML zu mischen und das auszulagern. Besser, weil logischer und besser wartbar, wäre das Layout in einem XSL-Template auszulagern.

              Das sehe ich immer noch anders.
              Ich habe eine XML-Datei mit dem Hauptlayout (cdcatalog_book.xml). Darin enthalten sind Platzhalter, die entweder durch die Daten in cdcatalog.xml oder durch weitere Layoutkomponenten ersetzt werden sollen. Die Layoutkomponenten selber sollen ebenfalls Platzhalter enthalten, die durch die Daten in cdcatalog.xml oder aus anderen daten.xml ersetzt werden sollen. Für mich ist das Layout der einzelnen Komponenten so viel besser händelbar, wenn diese in extra XML-Dateien abgelegt werden. Hier muss man einfach nur die Namen der Elemente und ggf. Attribute kennen, um das Design zu ändern. Eine Ablage in XSL erfordet die Kenntnis der Syntax von XSL - nur meine Meinung.

              Mit einem:
              <xsl:for-each select="document('cdcatalog_liste.xml')/*">[3]
                 xsl:apply-imports/
              </xsl:for-each>
              sollte es gehen.

              Ging auch ohne. Mit ist kein Unterschied zu merken.

              Mein Fehler. (Aber dein XSLT-Prozessor sollte auch meckern!)
              xsl:apply-imports/ kann nur innerhalb von xsl:template verwendet werden.

              Nö, hat er nicht. Ich verwende XSLTPROC.

              Weiters - auch mein Fehler, das übergesehen zu haben - in deinem zu importierenden XSL werden die Variablen zwar verwendet, aber nicht deklariert . (auch deshalb hätte dir eigentlich der Prozessor eine Fehlermelung liefern müssen)

              Ja, da hat er gemeckert, weil er die ja nicht kannte. Deshalb hatte ich sie auch erstmal auskommentiert.

              Ich habe keine Lösung dafür.

              Schade.

              Willst du unbedingt etwas auslagern, fände ich immer noch besser so (ebenfalls ohne "cdcatalog_liste.xml"):


              <?xml version="1.0" encoding="iso-8859-1"?>
              <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
              <xsl:include href="formatknoten.xsl" />
              <xsl:variable name="myXML" select="document('cdcatalog.xml')/catalog" />
              <xsl:template match="/">
                <xsl:apply-templates />
              </xsl:template>

              <xsl:template match="*[name() != 'cd_liste']">
                xsl:copy
                 <xsl:for-each select="@*">
                  <xsl:copy />
                 </xsl:for-each>
                 <xsl:apply-templates />
                </xsl:copy>
              </xsl:template>
              <xsl:template match="cd_liste">
                <xsl:call-template name="formatnode">
                 <xsl:with-param name="node" select="." />
                 <xsl:with-param name="documentNode" select="$myXML/cd" />
                 <xsl:with-param name="documentElements" select="$myXML/cd/title | $myXML/cd/artist" />
                 <xsl:with-param name="documentNodeElementName" select="'tr'" />
                 <xsl:with-param name="documentElementsElementName" select="'td'" />
                </xsl:call-template>
              </xsl:template>
              </xsl:stylesheet>

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

              <xsl:template name="formatnode">
                <xsl:param name="node" />
                <xsl:param name="documentNode" />
                <xsl:param name="documentElements" />
                <xsl:param name="documentNodeElementName" />
                <xsl:param name="documentElementsElementName" />
                <xsl:for-each select="$node">
                 <xsl:for-each select="$documentNode">
                  <xsl:element name="{$documentNodeElementName}">
                   <xsl:for-each select="current()/*[. = $documentElements]">
                    <xsl:element name="{$documentElementsElementName}">
                     <xsl:value-of select="." />
                    </xsl:element>
                   </xsl:for-each>
                  </xsl:element>
                 </xsl:for-each>
                </xsl:for-each>
              </xsl:template>

              </xsl:stylesheet>

              Die Auslagerung wäre schon hilfreich und würde das ganze vielleicht übersichtlicher machen. Am Beispiel der cdcatalog.xml habe ich nur versucht, das Problem hier darzustellen. In Wirklichkeit gehts um sehr viel komplexere Daten, die durch XSL in das richtige Layout gebracht werden sollen. Mein XSL-File dazu umfasst nun auch schon fast 2000 Zeilen, in dem halt das Layout der Daten enthalten ist. Die Auslagerung würde eventuell ein wenig Übersichtlichkeit zurückbringen. Außerdem vielleicht auch etwas mehr 'professioneller' aussehen, als alles in eine Datei zu hämmern.

              Ich danke Dir für die Diskussion und deine Hilfe. Den oberen Ansatz von Dir werde ich mal testen und schaun, ob mich das weiter bringt. Wenn nicht, muss ich wohl bei meiner jetzigen Lösung bleiben.

              Liebe Grüße,
              Kerstin

              1. Hallo Kerstin,

                Ehm ... na ja, genau das ist  - meine Meinung nach - falsch. Du versuchst Layout mit dem XML zu mischen und das auszulagern. Besser, weil logischer und besser wartbar, wäre das Layout in einem XSL-Template auszulagern.

                Das sehe ich immer noch anders.

                Das habe ich mir gedacht :)

                Ich habe eine XML-Datei mit dem Hauptlayout (cdcatalog_book.xml).

                Schon dabei hat sich mir der Megen verkrampft. Layout gehört schlicht nicht in das XML und ich würde das wirklich nicht behaupten, wenn ich nicht genügend Erfahrung auf dem Gebiet besäße, aber mehr dazu weiter unten.

                Für mich ist das Layout der einzelnen Komponenten so viel besser händelbar, wenn diese in extra XML-Dateien abgelegt werden. Hier muss man einfach nur die Namen der Elemente und ggf. Attribute kennen, um das Design zu ändern.

                Das ist nur scheinbar so. Was ist wenn sich das Layout ändert und du diese Änderungen machen musst? Wenn es eine größere Änderung ist, muss du dann über viele XML-Dateien was ändern und du wirst zusätzlich auch im XSL Änderungen machen müssen. Oder du legst noch mehr XML- und XSL-Dateien an und es wird irgendwann ziemlich unübersichtlich. (Z.B. gesetzt dem Fall, dass nicht nur HTML sondern auch PDF etc. als Ausgabeformat gewünscht wird, dann kannst du die "XML-Templates", die HTML Enthalten ganz vergessen und welche mit FO-Elementen anlegen usw.)

                Eine Ablage in XSL erfordet die Kenntnis der Syntax von XSL - nur meine Meinung.

                Das ist etwas widersprüchlich, denn erstens brauchst du jetzt wesentlich mehr Arbeit in die Entwicklung der XSLs zu stecken, denn die Lösungen die du brauchst, sind sehr spezifisch und so gut wie nicht wiederverwendbar und zweitens, ich verstehe nicht ganz was du meinst, denn die Syntax von XSL muss du so oder so kennen, wenn du damit arbeiten willst.

                Die Auslagerung wäre schon hilfreich und würde das ganze vielleicht übersichtlicher machen. Am Beispiel der cdcatalog.xml habe ich nur versucht, das Problem hier darzustellen. In Wirklichkeit gehts um sehr viel komplexere Daten, die durch XSL in das richtige Layout gebracht werden sollen.

                Das es sich nicht um ein kleines Heimprojekt handelt, habe ich schon auch so gedacht.

                Mein XSL-File dazu umfasst nun auch schon fast 2000 Zeilen, in dem halt das Layout der Daten enthalten ist. Die Auslagerung würde eventuell ein wenig Übersichtlichkeit zurückbringen. Außerdem vielleicht auch etwas mehr 'professioneller' aussehen, als alles in eine Datei zu hämmern.

                Da gebe ich dir ganz Recht. Ich habe nicht wenige Projkete mit XML und XSL realisiert. Da ist eine gutdurchdachte Teilung der XSLs sehr wichtig.
                Ich habe XSLs die sehr koplexe Ausgaben generieren, aber nur 50-60 Zeilen lang sind: dafür includieren sie aber mehrere andere XSLs und arbeiten sie dann nur mit call-templates. Ich habe solche XSL-Dateien, die nur Templates für die Formatierung und Ausgabe von Bilder, Falsh oder Videos enthalten und auch welche die nur Templates für Datumsformatierung usw. enthalten.
                Diese Template-XSLs kann ich aber dafür in beliebige andere XSL-Datein inkludieren und deren Funktionalität mit call-template oder apply-templates mit verschiedenden 'mod's nützten, egal ob ich PDF oder HTML oder SVG erzeuge.

                2000 Zeilen sind für eine einzelne alleinstehende XSL-Datei schon wirklich groß (Ich nehme an du hast ein paar sehr große for-each-Schleifen dinn?)
                Da müsstest du eingeltich die Datei ganz auseinanderpflücken und nachsehen welche Teilkomponente als eingenständiges Template erstellt werden kann. Dann kannst du damit anfangen solche Templates zu verallgemeinern (d.h. sie parametisieren) und sie schließlich dann in eigene XSLs auslagern.
                Wenn du aber versuchst diese Funktionalität in die XMLs auszulagern, wird dir das dein XSL kaum vereinfachen, sondern ihre Handhabung nur erschweren.
                Und was passiert, wenn sich mal das XML ändert? Es wird z.B. aus "autor" "performer"? (XMLs verden ja oft aus DB-Daten generiert, d.h. eine kleine Änderung der DB-Ausgabe wirkt sich auf alle generierten XMLs aus).
                Da musst du hergehen und alle deine XML-"Templates" durchsuchen um den "Platzhalter" auszutauschen und noch mehr: du musst vielleicht auch dein XSL ändern, denn vielleicht hast du ja irgendwo ein "name() = 'autor'" drinn.
                Dann ist es schon einfacher, wenn der Austausch nur in einem einzigen XSL und vielleicht nur in einem einzigen Template passieren muss.

                Natürlich möchte ich dich zu nichts überreden, aber ich denke, dass du auf diese Weise den falschen Weg zur Verinfachung einschlägst.

                Grüße
                Thomas

                1. Hallo Thomas,

                  Für mich ist das Layout der einzelnen Komponenten so viel besser händelbar, wenn diese in extra XML-Dateien abgelegt werden. Hier muss man einfach nur die Namen der Elemente und ggf. Attribute kennen, um das Design zu ändern.

                  Das ist nur scheinbar so. Was ist wenn sich das Layout ändert und du diese Änderungen machen musst? Wenn es eine größere Änderung ist, muss du dann über viele XML-Dateien was ändern und du wirst zusätzlich auch im XSL Änderungen machen müssen. Oder du legst noch mehr XML- und XSL-Dateien an und es wird irgendwann ziemlich unübersichtlich. (Z.B. gesetzt dem Fall, dass nicht nur HTML sondern auch PDF etc. als Ausgabeformat gewünscht wird, dann kannst du die "XML-Templates", die HTML Enthalten ganz vergessen und welche mit FO-Elementen anlegen usw.)

                  Hm ... wär eine Überlegung wert. Im Moment habe ich noch das HauptLayoutXML mit den Überschriften für die einzelnen Kapitel und den Platzhaltern und halt die DatenXML. Im XSL werden die Platzhalter durch die Daten aus der DatenXML und wie die Daten denn dargestellt werden sollen (als Tabelle oder Liste oder sonstwie) ersetzt. Weitere XML-Layout-Komponenten werde ich wohl so wie gedacht nicht hinbekommen. Das habe ich schon verstanden ... Darf ichs trotzdem doof finden, dass das net geht?

                  Das cdcatalog-Beispiel ist nur ein Beispiel. Das XML ist DocBook-XML, mit einem solchen XML kann ich dann ganz einfach per DocBook-XSL HTML, PDF und RTF genieren, da die Tags ja eh vorgegeben sind.

                  Das ist etwas widersprüchlich, denn erstens brauchst du jetzt wesentlich mehr Arbeit in die Entwicklung der XSLs zu stecken, denn die Lösungen die du brauchst, sind sehr spezifisch und so gut wie nicht wiederverwendbar und zweitens, ich verstehe nicht ganz was du meinst, denn die Syntax von XSL muss du so oder so kennen, wenn du damit arbeiten willst.

                  Ich meinte, ich ändere einfach die Anordnung der Tags in der XML ohne überhaupt das XSL noch einmal anzufassen. Die Platzhalter bleiben gleich. Die Platzhalter geben nur an, mit welchen Daten sie aus der DatenXML ersetzt werden sollen. Die Platzhalter können allerdings auch durch ganze Tabellen oder anderes ersetzt werden. Diesen sollten eben in andere XML-Dateien ebenfalls mit Platzhaltern versehen, abgespeichert werden. So kann ich in diesen unabhängig vom XSL bestimmen, wie die Tabelle aussehen soll und wie die Platzhalter angeordnet werden.

                  Ich habe XSLs die sehr koplexe Ausgaben generieren, aber nur 50-60 Zeilen lang sind: dafür includieren sie aber mehrere andere XSLs und arbeiten sie dann nur mit call-templates. Ich habe solche XSL-Dateien, die nur Templates für die Formatierung und Ausgabe von Bilder, Falsh oder Videos enthalten und auch welche die nur Templates für Datumsformatierung usw. enthalten.
                  Diese Template-XSLs kann ich aber dafür in beliebige andere XSL-Datein inkludieren und deren Funktionalität mit call-template oder apply-templates mit verschiedenden 'mod's nützten, egal ob ich PDF oder HTML oder SVG erzeuge.

                  Genau das versuche ich jetzt auch include, import bzw. call-templates zu verwenden. Bin noch ein klein wenig anfängerhaft und muss erst rausfinden, was alles möglich ist und was eben nicht.

                  2000 Zeilen sind für eine einzelne alleinstehende XSL-Datei schon wirklich groß (Ich nehme an du hast ein paar sehr große for-each-Schleifen dinn?)

                  ganz ganz viele for-each-Schleifen

                  Da müsstest du eingeltich die Datei ganz auseinanderpflücken und nachsehen welche Teilkomponente als eingenständiges Template erstellt werden kann. Dann kannst du damit anfangen solche Templates zu verallgemeinern (d.h. sie parametisieren) und sie schließlich dann in eigene XSLs auslagern.

                  Wie schon gesagt, versuch ich das gerade.

                  Wenn du aber versuchst diese Funktionalität in die XMLs auszulagern, wird dir das dein XSL kaum vereinfachen, sondern ihre Handhabung nur erschweren.
                  Und was passiert, wenn sich mal das XML ändert? Es wird z.B. aus "autor" "performer"? (XMLs verden ja oft aus DB-Daten generiert, d.h. eine kleine Änderung der DB-Ausgabe wirkt sich auf alle generierten XMLs aus).
                  Da musst du hergehen und alle deine XML-"Templates" durchsuchen um den "Platzhalter" auszutauschen und noch mehr: du musst vielleicht auch dein XSL ändern, denn vielleicht hast du ja irgendwo ein "name() = 'autor'" drinn.
                  Dann ist es schon einfacher, wenn der Austausch nur in einem einzigen XSL und vielleicht nur in einem einzigen Template passieren muss.

                  Also die Daten liegen ja eh in XML vor. Da sollen sie auch bleiben. Jetz gehts um die Darstellung, die ich ja eigentlich auch größtenteils in XML auslagern wollte. Scheinbar ist das aber nicht möglich. Wenn sich jetzt "author" in "performer" ändern sollte, müsste ich eh an dem XSL auch was ändern, weil ich ja dann nicht mehr auf den Tag "author" in der DatenXML zugreifen könnte. Eine Änderung ist nicht auszuschließen. Nur wenn ich die DatenXML ändere, muss ich noch lange nicht den Platzhalter im LayoutXML ändern oder umgekehrt.

                  Ich glaub, ich wiederhole mich mit dem was ich oben schreibe. Es ist auch wenig schwer das hier zu erklären. Ob ein Bild da mehr sagt, bezweifle ich.
                  Deine Tipps nehme ich wirklich ernst. Aufdrängeln lass ich mir wirklich auch nichts. Ich schaue halt, obs mir was bringt oder nicht. Hier per Forum jemanden genaustens zu erklären worum es geht, wäre zu aufwendig.
                  So, nun muss ich aber erstmal weiter machen und guggen, wo ich am Ende lande ...

                  Gruß,
                  Kerstin