Turok: Gleiche Spaltenlänge per XSL:FO

1. Kann ich mit XSL:FO erreichen, dass alle Spalten einer Seite die gleiche Länge bekommen? Die Spalten differieren um bis zu drei Zeilen.

2. Kann ich abfragen, ob bei der Ausgabe eines Datensatzes gerade eine neue Spalten bekonnen wurde? Ich möchte in diesem Fall eine andere Formatierung anwenden.

Herzlichen Dank
Turok

  1. Hallo,

    1. Kann ich mit XSL:FO erreichen, dass alle Spalten einer Seite die gleiche Länge bekommen? Die Spalten differieren um bis zu drei Zeilen.

    Ja. Eine Tabelle in XLF-FO verhält sich hierbei nicht anderes als eine HTML-Tabelle

    1. Kann ich abfragen, ob bei der Ausgabe eines Datensatzes gerade eine neue Spalten bekonnen wurde? Ich möchte in diesem Fall eine andere Formatierung anwenden.

    Das kommt darauf an.
    Ich könnte jetzt einfach "Ja" sagen, aber das würde dir nicht helfen.

    Weitere Hilfe ist nur dann möglich, wenn du auch deinen (Teil) Code dazugibst.

    Grüße
    Thomas

    1. Hallo Thomas,

      Ja. Eine Tabelle in XLF-FO verhält sich hierbei nicht anderes als eine HTML-Tabelle

      Ich glaube, ich habe mich etwas unklar ausgedrückt. Die Spalten selbst sind natürlich immer gleichlang. Ich möchte vielmehr den Text darin so ausrichten, dass die Spalten immer in kompletter Höhe ausgefüllt werden, also vertikaler Blocksatz.

      Das kommt darauf an.
      Ich könnte jetzt einfach "Ja" sagen, aber das würde dir nicht helfen. Weitere Hilfe ist nur dann möglich, wenn du auch deinen (Teil) Code dazugibst.

      <xsl:template match="name">
      fo:block
      <xsl:apply-templates select="nachname"/>
      <xsl:apply-templates select="vorname"/>
      <xsl:apply-templates select="strasse"/>
      <xsl:apply-templates select="nummer"/>
      </fo:block>

      <xsl:template match="nachname">
      xsl:choose
      <xsl:when test="./text() = preceding::nachname/text()">
      xsl:text-</xsl:text>
      </xsl:when>
      xsl:otherwise
      <xsl:value-of select="."/>
      </xsl:otherwise>
      </xsl:choose>
      xsl:text </xsl:text>
      </xsl:template>

      Es handelt sich um Adressen, die jeweils in einem Absatz hintereinanderweg in einem mehrspaltigen Dokument ausgegeben werden. Das zweite Template soll für den Nachnamen nur einen '-' ausgeben, wenn diese identisch zum vorhergehenden Nachnamen ist.

      Ciao
      Turok

      1. Hallo,

        Ja. Eine Tabelle in XLF-FO verhält sich hierbei nicht anderes als eine HTML-Tabelle

        Ich glaube, ich habe mich etwas unklar ausgedrückt. Die Spalten selbst sind natürlich immer gleichlang. Ich möchte vielmehr den Text darin so ausrichten, dass die Spalten immer in kompletter Höhe ausgefüllt werden, also vertikaler Blocksatz.

        Wenn  du nur einen Text auf die spalten verteilen musst, geht das.
        Etwas kompliziert, aber möglich: du teilst die Gesamtlänge des Textes durch die Anzahl der Spalten und füllst nur jeweils den entsprechenden Textteil in die Spalte.
        Im Archiv gibt es von mir ein Template für eine Lösung mit zwei Spalten (zwar für HTML, aber das ist in Prinzip dasselbe), wo auch das Wortende brücksichtigt wird (damit ein Wort nicht mitten drinn zerschnitten wird)

        Willst du Texte aus verschiedenen Elementen so auf die Spalten verteilen, müsstest du zuerst diese Texte zu einem String machen und dann wie weiter oben verfahren.

        Das kommt darauf an.
        Ich könnte jetzt einfach "Ja" sagen, aber das würde dir nicht helfen. Weitere Hilfe ist nur dann möglich, wenn du auch deinen (Teil) Code dazugibst.

        <xsl:template match="name">
        fo:block
        <xsl:apply-templates select="nachname"/>
        <xsl:apply-templates select="vorname"/>
        <xsl:apply-templates select="strasse"/>
        <xsl:apply-templates select="nummer"/>
        </fo:block>

        <xsl:template match="nachname">
        xsl:choose
        <xsl:when test="./text() = preceding::nachname/text()">
        xsl:text-</xsl:text>
        </xsl:when>
        xsl:otherwise
        <xsl:value-of select="."/>
        </xsl:otherwise>
        </xsl:choose>
        xsl:text </xsl:text>
        </xsl:template>

        Es handelt sich um Adressen, die jeweils in einem Absatz hintereinanderweg in einem mehrspaltigen Dokument ausgegeben werden. Das zweite Template soll für den Nachnamen nur einen '-' ausgeben, wenn diese identisch zum vorhergehenden Nachnamen ist.

        Es tut mir leid, ich verstehe das Problem noch immer nicht.
        Was funktioniert an deinem Template nicht?
        Mal davon abgesehene, dass ich es so schreiben würde:

        <xsl:template match="nachname">
        <xsl:when test=". = preceding::nachname">
        ....

        Was aber trotzdem und immer noch davon ausgeht, dass innerhalb von einem <name>-Element mehrere <nachname>-Elemente vorkommen können.

        Grüße
        Thomas

        1. Hi,

          Wenn  du nur einen Text auf die spalten verteilen musst, geht das.
          Etwas kompliziert, aber möglich: du teilst die Gesamtlänge des Textes durch die Anzahl der Spalten und füllst nur jeweils den entsprechenden Textteil in die Spalte.
          Im Archiv gibt es von mir ein Template für eine Lösung mit zwei Spalten (zwar für HTML, aber das ist in Prinzip dasselbe), wo auch das Wortende brücksichtigt wird (damit ein Wort nicht mitten drinn zerschnitten wird)

          Ich glaube, da liegt immer noch ein Missverständnis vor. Es ist so, dass eine ausgegebene Adresse auf eine Zeile passen kann, sie kann aber auch bis zu drei Zeilen benötigen, je nach Länge. Wäre jede Adresse nur eine Zeile lang, wären die Spalten ja unten jeweils bis zum Rand ausgefüllt. Ich möchte nun aber verhindern, dass eine mehrzeilige Adresse am Ende einer Spalte auseinandergerissen wird, wenn der Platz nicht reicht. Die Adresse soll also zusammengehalten werden und wird damit automatisch auf die nächste Spalte umbrochen. Den entsprechenden Code habe ich hier zwecks Übersicht entfernt. Dadurch bleiben aber ein oder zwei Zeilen am Ende der Spalte leer. Der Text in der Spalte soll nun vertikal so ausgedehnt werden, dass diese Leerzeilen ausgefüllt werden. Eben Blocksatz, wie ich das auch z.B. in QuarkXPress machen kann. Dein HTML-Template dürfte mir da leider nicht weiterhelfen, da es ein reines XSL:FO Problem ist.

          Es tut mir leid, ich verstehe das Problem noch immer nicht.
          Was funktioniert an deinem Template nicht?

          Das Template funktioniert schon. Ich suchte nur nach einer Möglichkeit abzufragen, ob mit dem Ausgeben des aktuellen Datensatzes gerade eine neue Spalte begonnen wurde. Ich möchte diese IF-Schleife um eben diese Abfrage ergänzen, da die erste Adresse eine neuen Spalte _immer_ mit ausgeschriebenen Nachnamen erfolgen soll.

          <xsl:when test=". = preceding::nachname" and (...AbfrageNeueSpalte...)>

          Was aber trotzdem und immer noch davon ausgeht, dass innerhalb von einem <name>-Element mehrere <nachname>-Elemente vorkommen können.

          Es kommt auf jeden Fall nur eines vor.

          Gruß
          Turok

          1. Hallo,

            Ich glaube, da liegt immer noch ein Missverständnis vor.

            Normalerweise bin ich nicht so begrifstutzig ;-) aber ich habe glaube einen Brett vor dem Kopf.

            »»Es ist so, dass eine ausgegebene Adresse auf eine Zeile passen kann, sie kann aber auch bis zu drei Zeilen benötigen, je nach Länge. Wäre jede Adresse nur eine Zeile lang, wären die Spalten ja unten jeweils bis zum Rand ausgefüllt.

            spalte 1           spalte 2          spalte 3
              -----------------  ----------------  ------------------
            1 |  adressse       |  adresse        |    adresse      |
            2 |                 |    in drei      |                 |
            3 |                 |    zeilen       |                 |
              -----------------  ----------------  ------------------
            1 |  adressse       |  adresse        |    adresse      |
            2 |                 |                 | in zwei  zeile  |
            3 |                 |                 |                 |
              -----------------  ----------------  ------------------

            Ich möchte nun aber verhindern, dass eine mehrzeilige Adresse am Ende einer Spalte auseinandergerissen wird, wenn der Platz nicht reicht. Die Adresse soll also zusammengehalten werden und wird damit automatisch auf die nächste Spalte umbrochen.

            Wenn ich dich jetzt richtig verstehe solltest du das Attribut
            »keep-with-next.within-column="always"« verwenden. Dies kann bei
            "block-level formatting objects, inline formatting objects, fo:list-item, and fo:table-row" benüzt werden.

            »»Dadurch bleiben aber ein oder zwei Zeilen am Ende der Spalte leer. Der Text in der Spalte soll nun vertikal so ausgedehnt werden, dass diese Leerzeilen ausgefüllt werden. Eben Blocksatz, wie ich das auch z.B. in QuarkXPress machen kann.

            Das verstehe ich wiederum leider nicht. (Ich kann mir es visuell nicht vorstellen was du meinst) Wenn der Text nur eine Zeile in Ansprich nimmt, nimmt es eben nur eine Zeile in Anspruch.
            Du kannst den TExt entweder nach unten ausrichten, oder mit "word-spacing" oder "letter-spacing" spielen.

            Es tut mir leid, ich verstehe das Problem noch immer nicht.
            Was funktioniert an deinem Template nicht?

            Das Template funktioniert schon. Ich suchte nur nach einer Möglichkeit abzufragen, ob mit dem Ausgeben des aktuellen Datensatzes gerade eine neue Spalte begonnen wurde. Ich möchte diese IF-Schleife um eben diese Abfrage ergänzen, da die erste Adresse eine neuen Spalte _immer_ mit ausgeschriebenen Nachnamen erfolgen soll.

            <xsl:when test=". = preceding::nachname" and (...AbfrageNeueSpalte...)>

            Ich glaube zu verstehen was du meinst.
            Nein, das ist nicht möglich. Bzw. du müsstest sehr vieles ausrechnen, angefangen von der noch zur Verfügung stehenden Platzes in der Seite, in der Spalte, Textlänge und das ganze versuchen in einer Variable ausrechenen, das geht dann deshalb nicht, weil du eigentich den Transfomationsprozess sebst überwachen und dann in diesem Prozess aktiv eingreifen müsstest.

            Was aber trotzdem und immer noch davon ausgeht, dass innerhalb von einem <name>-Element mehrere <nachname>-Elemente vorkommen können.

            Es kommt auf jeden Fall nur eines vor.

            Das ist die Abfrage falsch.

            Grüße
            Thomas