Alex: Querverweise

Hallo alle zusammen,

ich möchte gerne Querverweise zwischen einzelnen "Kapiteln" einer Webseite erstellen. Jedes Kapitel wird in ein eigenständiges HTML-Dokument transformiert und soll per Hyperlink auf andere explizit referenzierte Kapitel verweisen. Das scheint mit der Funktion id() recht einfach realisierbar zu sein, solange alle Kapitel in der selben XML-Datei vorliegen. Gibt es Probleme mit diesem Ansatz, wenn jedes Kapitel seine eigene XML-Datei bekommt und somit IDs über Dateigrenzen hinweg gesucht werden müßten, um die Querverweise zu erstellen?

Was spricht für bzw. gegen die Aufteilung der Kapitel auf mehrere XML-Dokumente? Wie wird das z.B. für SELFHTML 9 gehandhabt (falls einer der Mitwirkenden das hier liest)?

Grüße

Alex

  1. Hallo,

    Das scheint mit der Funktion id() recht einfach realisierbar zu sein, solange alle Kapitel in der selben XML-Datei vorliegen.

    Genau.

    Gibt es Probleme mit diesem Ansatz, wenn jedes Kapitel seine eigene XML-Datei bekommt und somit IDs über Dateigrenzen hinweg gesucht werden müßten, um die Querverweise zu erstellen?

    Jain.

    Was spricht für bzw. gegen die Aufteilung der Kapitel auf mehrere XML-Dokumente? Wie wird das z.B. für SELFHTML 9 gehandhabt (falls einer der Mitwirkenden das hier liest)?

    Es spricht nichts gegen die Aufteilung, so lange dafür gesorgt wird, dass die nachfolgenden Prozesse über die nötige Informationen der Zuordnung verfügen.

    Diese übergreifende Zuordnung geschieht bei SELFHTML 9 über eine zentrale Index-Datei, in der die IDs auf alle existierende (und auch auf die noch gar nicht existierende) XML-Dateien hinterlegt sind.
    Das XSLT was z.B. die "nightly build" von SELFHTML macht, arbeitet sich anhand diese Datei durch.

    [https://redaktion.selfhtml.org/wiki/SDML]

    Grüße
    Thomas

    1. Hallo Thomas,

      Es spricht nichts gegen die Aufteilung, so lange dafür gesorgt wird, dass die nachfolgenden Prozesse über die nötige Informationen der Zuordnung verfügen.

      Diese übergreifende Zuordnung geschieht bei SELFHTML 9 über eine zentrale Index-Datei, in der die IDs auf alle existierende (und auch auf die noch gar nicht existierende) XML-Dateien hinterlegt sind.

      Gut, dann schau ich mal, ob das für meine Anwendung auch ein möglicher Weg wäre. Danke.

      Ich hab noch eine weitere Frage zu Verweisen:

      Ich erstelle innerhalb eines Kapitels u.a. Abbildungen mit Bildunterschrift und einer automatischen Numerierung. Letzteres realisiere ich mit xsl:number/. Ein Abbildung bekommt z.B. als Unterschrift "Abbildung 1: Ein Schuhkarton". Innerhalb des Textes im Kapitel möchte ich diese Abbildungen ebenfalls referenzieren können. Dazu soll z.B. <ref refid="schuhkarton"/> durch "Abbildung 1" ersetzt werden, also mit der gleich Numerierung wie schon in der Bildunterschrift.

      Krieg ich irgendwie aus meinen Abbildungen die dynamisch generierte Unterschrift heraus oder kann ich gar nicht sicherstellen, daß das Template für die Abbildungen _vor_ dem Template für die Referenzen abgearbeitet wird? Bleibt also nur das nochmalige Berechnen der Numerierung innerhalb des Templates für <ref>?

      Grüße

      Alex

      1. Hallo,

        Gut, dann schau ich mal, ob das für meine Anwendung auch ein möglicher Weg wäre. Danke.

        Als alternative kannst du natürlich komplett auf XInclude zurückgreifen und so deine Kapitel-XMLs zusammenstellen (machen wir auch bei SELFHTML 9)

        Ich hab noch eine weitere Frage zu Verweisen:

        Ich erstelle innerhalb eines Kapitels u.a. Abbildungen mit Bildunterschrift und einer automatischen Numerierung. Letzteres realisiere ich mit xsl:number/. Ein Abbildung bekommt z.B. als Unterschrift "Abbildung 1: Ein Schuhkarton". Innerhalb des Textes im Kapitel möchte ich diese Abbildungen ebenfalls referenzieren können. Dazu soll z.B. <ref refid="schuhkarton"/> durch "Abbildung 1" ersetzt werden, also mit der gleich Numerierung wie schon in der Bildunterschrift.

        Krieg ich irgendwie aus meinen Abbildungen die dynamisch generierte Unterschrift heraus oder kann ich gar nicht sicherstellen, daß das Template für die Abbildungen _vor_ dem Template für die Referenzen abgearbeitet wird? Bleibt also nur das nochmalige Berechnen der Numerierung innerhalb des Templates für <ref>?

        Das kommt darauf an ob du mit XSLT 2.0 arbeiten kannst. Dort gäbe es Möglichkeiten die Bilder alle in einer Variable zu laden und so auf sie zurückgreifen.
        In XSLT 1.0 geht das nicht und xsl:number fügt die generierte Nummer in das Ergebnisbaum ein, d.h. du "kann[st] gar nicht sicherstellen, daß das Template für die Abbildungen _vor_ dem Template für die Referenzen abgearbeitet wird"

        Grüße
        Thomas

        1. Hallo Thomas,

          »» Gut, dann schau ich mal, ob das für meine Anwendung auch ein möglicher Weg wäre. Danke.

          Als alternative kannst du natürlich komplett auf XInclude zurückgreifen und so deine Kapitel-XMLs zusammenstellen (machen wir auch bei SELFHTML 9)

          Danke für den Tip. Werde ich mit in die Recherche aufnehmen. :-)

          »» Krieg ich irgendwie aus meinen Abbildungen die dynamisch generierte Unterschrift heraus oder kann ich gar nicht sicherstellen, daß das Template für die Abbildungen _vor_ dem Template für die Referenzen abgearbeitet wird? Bleibt also nur das nochmalige Berechnen der Numerierung innerhalb des Templates für <ref>?

          Das kommt darauf an ob du mit XSLT 2.0 arbeiten kannst. Dort gäbe es Möglichkeiten die Bilder alle in einer Variable zu laden und so auf sie zurückgreifen.

          XSLT 2 steht mir prinzipiell zur Verfügung. Gearbeitet hab ich bei meinen bisherigen Versuchen allerdings nur mit Features der Version 1.

          Grüße

          Alex

        2. Hallo Thomas,

          Das kommt darauf an ob du mit XSLT 2.0 arbeiten kannst. Dort gäbe es Möglichkeiten die Bilder alle in einer Variable zu laden und so auf sie zurückgreifen.

          Ich hab ein bißchen nachgelesen, um herauszufinden, wie das funktionieren könnte. Allerdings sprang mir mit meinen bescheidenen Erfahrung zum Thema XSLT nur die schon in XSLT 1.0 vorhandene Funktion key ins Auge. Das war's wohl nicht, was Du in eine Variable laden wolltest. Naja, wie auch immer ...

          Mit xsl:key könnte ich einen Index über alle Abbildungen des Kapitels erstellen, in dem sie nach ihrer ID, die auch für die Referenzierung benutzt wird, unterschieden werden. Nun kriege ich mit key() zwar die Abbildung mit einer bestimmten ID, habe aber keine Idee, wie ich die Information gewinnen kann, um die wievielte Abbildung es sich im Kapitel handelt. Also nicht viel anders, als hätte ich einfach id() benutzt.

          Könntest Du ein Beispiel dafür geben, welche Lösung Dir zu diesem Problem vorschwebte?

          Grüße

          Alex

          1. Hallo,

            »» Das kommt darauf an ob du mit XSLT 2.0 arbeiten kannst. Dort gäbe es Möglichkeiten die Bilder alle in einer Variable zu laden und so auf sie zurückgreifen.

            Ich hab ein bißchen nachgelesen, um herauszufinden, wie das funktionieren könnte. Allerdings sprang mir mit meinen bescheidenen Erfahrung zum Thema XSLT nur die schon in XSLT 1.0 vorhandene Funktion key ins Auge. Das war's wohl nicht, was Du in eine Variable laden wolltest. Naja, wie auch immer ...

            Könntest Du ein Beispiel dafür geben, welche Lösung Dir zu diesem Problem vorschwebte?

            In XSLT 2.0 ist es möglich in Variablen temporäre bäume zu speichern und dann auf diesem Baum zuzugrifen.
            Hier mal sehr grob geschildert wir das gehen könnte. Das ist hier wirklich nur eine Skizze, zwar könnte es so auch funktionieren, aber wenn man das XML kennt, kämen vermutlich auch andere Möglichkeiten in Betracht.

              
            	<xsl:variable name="bilder">  
            		<xsl:for-each select="//bild">  
            			<tempbild name="{@name}" src="{@src}" id="{@id}">  
            				<xsl:attribute name="number">  
            					<xsl:number count="multiple" />  
            				</xsl:attribute>  
            			</tempbild>  
            		</xsl:for-each>  
            	</xsl:variable>  
            	<xsl:template match="bild">  
            		<xsl:variable name="bildid" select="@id" />  
            		<xsl:value-of select="$bilder/tempbild[@id = $bildid]/@number"></xsl:value-of>		  
            	</xsl:template>  
            	<xsl:template match="bildreferenz">  
            		<xsl:variable name="bildid" select="@id" />  
            		<xsl:value-of select="$bilder/tempbild[@id = $bildid]/@number"></xsl:value-of>		  
            	</xsl:template>  
            
            

            Mit xsl:key könnte ich einen Index über alle Abbildungen des Kapitels erstellen, in dem sie nach ihrer ID, die auch für die Referenzierung benutzt wird, unterschieden werden. Nun kriege ich mit key() zwar die Abbildung mit einer bestimmten ID, habe aber keine Idee, wie ich die Information gewinnen kann, um die wievielte Abbildung es sich im Kapitel handelt. Also nicht viel anders, als hätte ich einfach id() benutzt.

            Hm....das könnte man noch herausfinden, aber wenn ich dich richtig verstanden habe, geht es dir ja nicht nur um "viel vieles Bild bist du in Kapitel"?

            Grüße
            Thomas

            1. Hallo Thomas,

              <xsl:variable name="bilder">
              <xsl:for-each select="//bild">
              <tempbild name="{@name}" src="{@src}" id="{@id}">
              <xsl:attribute name="number">
              <xsl:number count="multiple" />
              </xsl:attribute>
              </tempbild>
              </xsl:for-each>
              </xsl:variable>
              <xsl:template match="bild">
              <xsl:variable name="bildid" select="@id" />
              <xsl:value-of select="$bilder/tempbild[@id = $bildid]/@number"></xsl:value-of>
              </xsl:template>
              <xsl:template match="bildreferenz">
              <xsl:variable name="bildid" select="@id" />
              <xsl:value-of select="$bilder/tempbild[@id = $bildid]/@number"></xsl:value-of>
              </xsl:template>

                
              Ah, verstehe. Du legst die automatisch ermittelte Numerierung der Abbildungen jeweils in einem eigens dafür erstellten Attribut der Abbildung ab, speicherst diesen Ergebnisbaum in $bilder und liest nachher beim Referenzieren genau dieses Attribut wieder aus.  
                
              Ich habe gestern eher vermutet, daß die Numerierung aus dem Index der jeweiligen Abbildung in einer Art Array abgeleitet wird. Kein Wunder, daß ich damit nicht so weit gekommen bin. ;-)  
                
                
              
              > »» Also nicht viel anders, als hätte ich einfach id() benutzt.  
              > »»  
              >   
              > Hm....das könnte man noch herausfinden, aber wenn ich dich richtig verstanden habe, geht es dir ja nicht nur um "viel vieles Bild bist du in Kapitel"?  
                
              Den letzten Teil dieses Satzes hab ich nicht ganz verstanden.  
                
              Im Prinzip genügt es, zumindest die \_Bild\_referenzen betreffend, wenn das tatsächlich nur innerhalb eines Kapitels funktioniert, nicht über Kapitelgrenzen (und somit Dokumentgrenzen) hinweg. Das könnte z.B. so aussehen:  
                
              ~~~xml
                
              <content>  
              	<text>...</text>  
              	<figure id="schuhkarton">  
              		<src>bilder/schuhkarton.jpg</src>  
              		<caption>Ein Schuhkarton</caption>  
              	</figure>  
              	<text>...</text>  
              	<text>Der handelsübliche Schuhkarton in <xref refid="schuhkarton" /> ist ein sehr anspruchsloses Haustier ...</text>  
              </content>  
              
              

              Für die Abbildungen selber kommt dann dieses Template zur Anwendung:

                
              <xsl:template match="figure">  
              	<div class="figure">  
              		<img src="{src}" alt="" />  
              		<p class="caption">  
              			<span class="title">Abb. <xsl:number level="single" count="figure" />:</span>  
              			<xsl:text> </xsl:text>  
              			<xsl:value-of select="caption" />  
              		</p>  
              	</div>  
              </xsl:template>  
              
              

              Die automatische Numerierung gibt also nur an, um die wievielte Abbildung in diesem Kapitel es sich handelt (falls es das ist, was Du oben meintest). Das reicht so völlig aus. Deine oben vorgeschlagenen Lösung sollte für mein zu bauendes xref-Template ganz gut funktionieren, denke ich.

              Wenn Du dennoch Verbesserungsvorschläge hast, immer her damit! :-)

              Auf jeden Fall schonmal vielen Dank für die bisherige Hilfe.

              Grüße

              Alex

            2. Hallo Thomas,

              ich habe Probleme damit, den temporären Ergebnisbaum auszulesen, der zu Testzwecken folgendermaßen erstellt wird:

                
              <xsl:variable name="figure-list">  
              	<xsl:for-each select="//figure">  
              		<tmp>  
              			<caption><xsl:value-of select="caption" /></caption>  
              		</tmp>  
              	</xsl:for-each>  
              </xsl:variable>  
              
              

              Im Template liefert mir <xsl:value-of select="$figure-list" /> nun zwar den Inhalt aller <figure>s (das Anlegen dieser Liste funktioniert offensichtlich), allerdings erhalte ich mit <xsl:value-of select="$figure-list/tmp[1]" /> oder ähnlichen Versuchen, auf die einzelnen Elemente zuzugreifen stets ein leeres Ergebnis.

              Wenn ich es richtig verstanden habe, ist ja genau die Möglichkeit, auf diesem mit xsl:variable erzeugten Ergebnisbaum ganz normal mit XPath zu operieren die Verbesserung gegenüber XSLT 1.0. Was mache ich hier falsch? Ich hantiere mit Saxon-B 8.9, der sollte das doch können ...

              Grüße

              Alex

              1. Hallo,

                ich habe Probleme damit, den temporären Ergebnisbaum auszulesen, der zu Testzwecken folgendermaßen erstellt wird:

                so in Kürze: ich werde mir das ansehen.

                Grüße
                Thomas

              2. Hallo,

                ich habe Probleme damit, den temporären Ergebnisbaum auszulesen, der zu Testzwecken folgendermaßen erstellt wird:

                <xsl:variable name="figure-list">
                <xsl:for-each select="//figure">
                <tmp>
                <caption><xsl:value-of select="caption" /></caption>
                </tmp>
                </xsl:for-each>
                </xsl:variable>

                  
                Das ist so korrekt.  
                  
                  
                
                > Im Template liefert mir `<xsl:value-of select="$figure-list" />`{:.language-xml} nun zwar den Inhalt aller <figure>s (das Anlegen dieser Liste funktioniert offensichtlich), allerdings erhalte ich mit `<xsl:value-of select="$figure-list/tmp[1]" />`{:.language-xml} oder ähnlichen Versuchen, auf die einzelnen Elemente zuzugreifen stets ein leeres Ergebnis.  
                >   
                  
                Es sollte so etwas sein:  
                <xsl:value-of  select="$figure-list/tmp[1]/caption" /> denn du hast ja noch <caption> da drinn (wobei das an sich auch ohne funktioniert).  
                  
                ~~~xml
                  
                <content>  
                	<figure id="schuhkarton">  
                		<src>bilder/schuhkarton.jpg</src>  
                		<caption>Ein Schuhkarton</caption>  
                	</figure>  
                	<figure id="schuhkarton">  
                		<src>bilder/schuhkarton.jpg</src>  
                		<caption>xxxxx Ein Schuhkarton</caption>  
                	</figure>  
                	<figure id="schuhkarton">  
                		<src>bilder/schuhkarton.jpg</src>  
                		<caption>yyyyyyyyyyyy Ein Schuhkarton</caption>  
                	</figure>  
                	<text>...</text>  
                	<figure id="schuhkarton">  
                		<src>bilder/schuhkarton.jpg</src>  
                		<caption>zzzzzzzzzzzz Ein Schuhkarton</caption>  
                	</figure>  
                </content>  
                  
                <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">  
                	<xsl:output method="xml" indent="yes" />  
                	<xsl:variable name="figure-list">  
                		<xsl:for-each select="//figure">  
                			<tmp>  
                				<caption><xsl:value-of select="caption" /></caption>  
                			</tmp>  
                		</xsl:for-each>  
                	</xsl:variable>  
                	<xsl:template match="/">  
                		<abcd>  
                			<xsl:value-of  select="$figure-list/tmp[2]/caption" />  
                		</abcd>  
                	</xsl:template>  
                </xsl:stylesheet>  
                
                

                Ergebnis:
                <abcd>xxxxx Ein Schuhkarton</abcd>

                Grüße
                Thomas

                1. Hallo Thomas,

                  ich habe inzwischen herausgefunden, was das Problem war. Für Dich natürlich schwer zu erraten, weil ich nicht das gesamte Stylesheet hier gepostet habe. Aber daran sieht man mal, daß ich lange an völlig falscher Stelle suchte. ;-)

                    
                  <?xml version="1.0" encoding="utf-8" ?>  
                  <xsl:stylesheet version="2.0"  
                  	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  
                  	xmlns="http://www.w3.org/1999/xhtml">  
                    
                  <xsl:output  
                  	encoding="utf-8"  
                  	indent="yes"  
                  	method="xml"  
                  	omit-xml-declaration="yes"  
                  	doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"  
                  	doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"  
                  />  
                    
                  <xsl:variable name="figure-list">  
                  	...  
                  </xsl:variable>  
                    
                  <xsl:template match="/">  
                  	<html>...</html>  
                  </xsl:template>  
                    
                  <!-- ... noch mehr Templates ... -->  
                    
                  </xsl:stylesheet>  
                  
                  

                  Das Problem ist hierbei offensichtlich der (unbenannte) Default Namespace http://www.w3.org/1999/xhtml, denn wenn ich ihn nicht drin habe, kann ich auch wie erwartet auf die Variableninhalte zugreifen. Natürlich wirft das für mich jetzt erstmal ein paar Folgeprobleme auf, da ich gerne auch weiterhin XHTML 1.0 Strict als Output generieren möchte, aber das krieg ich hoffentlich noch hin.

                  Grüße

                  Alex

                  1. Hallo,

                    Das Problem ist hierbei offensichtlich der (unbenannte) Default Namespace http://www.w3.org/1999/xhtml, denn wenn ich ihn nicht drin habe, kann ich auch wie erwartet auf die Variableninhalte zugreifen. Natürlich wirft das für mich jetzt erstmal ein paar Folgeprobleme auf, da ich gerne auch weiterhin XHTML 1.0 Strict als Output generieren möchte, aber das krieg ich hoffentlich noch hin.

                    einzige nötige Änderung ist:
                    <xsl:value-of select="$figure-list/tmp[1]/caption" xpath-default-namespace="http://www.w3.org/1999/xhtml"/>

                    Grüße
                    Thomas

                    1. Hallo Thomas,

                      »» Das Problem ist hierbei offensichtlich der (unbenannte) Default Namespace http://www.w3.org/1999/xhtml, denn wenn ich ihn nicht drin habe, kann ich auch wie erwartet auf die Variableninhalte zugreifen. Natürlich wirft das für mich jetzt erstmal ein paar Folgeprobleme auf, da ich gerne auch weiterhin XHTML 1.0 Strict als Output generieren möchte, aber das krieg ich hoffentlich noch hin.

                      einzige nötige Änderung ist:
                      <xsl:value-of select="$figure-list/tmp[1]/caption" xpath-default-namespace="http://www.w3.org/1999/xhtml"/>

                      Hey, tausend Dank!

                      Grüße

                      Alex