Handbuch durchsuchen:

- Startseite
- Einleitung
- Hallo Welt!
- Grundlagen
  - Erstellen eines Layoutregelwerks
  - Aufbau der Datendatei und des Layoutregelwerks
  - Objekte ausgeben
  - Raster
  - Bereiche auf der Seite (PositioningArea)
  - Dateiorganisation
  - Silbentrennung / Spracheinstellungen
  - Einbinden von Schriftarten
  - Textformate
  - Textformatierung
  - Farben
- Programmierung
- Bilder einbinden
- Tabellen
- Fortgeschrittene Themen
  - Lesezeichen (Bookmarks)
  - Erzeugen von XML-Strukturen
  - Druckausgabe / Schnittmarken
  - CSS
  - Gruppen (virtuelle Objekte)
  - Virtuelle Seiten
  - Rotieren von Inhalten
  - Sortieren von Daten
  - Umfließen von Bildern
  - Seitentypen
  - Starten des Publishers über den Hotfolder
  - Lua-Filter / Datenvorverarbeitung
  - Schemavalidierung
  - Qualitätssicherung (PDF-Vergleich)
  - Fehlersuche / Debugging
  - Servermodus
- Kochbuch
  - Griffmarken
  - Mehrseitige PDF-Dateien einbinden
  - Layoutoptimierung mithilfe von Gruppen
  - Verzeichnisse erstellen
  - Seitenzahlen: Seite x von y
  - Aufzählungslisten nachahmen
- Installationsanleitung
- Voreinstellungen im speedata Publisher
- Starten des Publishers über die Kommandozeile
- Konfiguration des Publishers
- Längenangaben und Maßeinheiten
- XPath- und Layoutfunktionen
- Interne Variablen
- Liste der Änderungen
- Glossar
- Befehlsreferenz
  - A
  - Action
  - AddSearchpath
  - AtPageCreation
  - AtPageShipout
  - AttachFile
  - Attribute
  - B
  - Barcode
  - Bold
  - BoldItalic
  - Bookmark
  - Box
  - Br
  - Case
  - Circle
  - Color
  - Column
  - Columns
  - Compatibility
  - Contents
  - Copy-of
  - DefineColor
  - DefineFontalias
  - DefineFontfamily
  - DefineTextformat
  - Element
  - Fontface
  - ForAll
  - Frame
  - Grid
  - Group
  - Groupcontents
  - HSpace
  - Hyphenation
  - I
  - Image
  - Include
  - Initial
  - InsertPages
  - Italic
  - Layout
  - Li
  - LoadDataset
  - LoadFontfile
  - Loop
  - Makeindex
  - Margin
  - Mark
  - Message
  - NewPage
  - NextFrame
  - NextRow
  - NoBreak
  - Ol
  - Options
  - Otherwise
  - Output
  - Overlay
  - Pageformat
  - Pagetype
  - Paragraph
  - PDFOptions
  - PlaceObject
  - Position
  - PositioningArea
  - PositioningFrame
  - ProcessNode
  - Record
  - Regular
  - Rule
  - SaveDataset
  - SavePages
  - SetGrid
  - SetVariable
  - SortSequence
  - Stylesheet
  - Span
  - Sub
  - Sup
  - Switch
  - Table
  - Tablefoot
  - Tablehead
  - Tablerule
  - Td
  - Text
  - Textblock
  - Tr
  - Trace
  - Transformation
  - U
  - Ul
  - Until
  - URL
  - Value
  - VSpace
  - While

Version 3.2.0
Handbuch durchsuchen:

- Startseite
- Einleitung
- Hallo Welt!
- Grundlagen
  - Erstellen eines Layoutregelwerks
  - Aufbau der Datendatei und des Layoutregelwerks
  - Objekte ausgeben
  - Raster
  - Bereiche auf der Seite (PositioningArea)
  - Dateiorganisation
  - Silbentrennung / Spracheinstellungen
  - Einbinden von Schriftarten
  - Textformate
  - Textformatierung
  - Farben
- Programmierung
- Bilder einbinden
- Tabellen
- Fortgeschrittene Themen
  - Lesezeichen (Bookmarks)
  - Erzeugen von XML-Strukturen
  - Druckausgabe / Schnittmarken
  - CSS
  - Gruppen (virtuelle Objekte)
  - Virtuelle Seiten
  - Rotieren von Inhalten
  - Sortieren von Daten
  - Umfließen von Bildern
  - Seitentypen
  - Starten des Publishers über den Hotfolder
  - Lua-Filter / Datenvorverarbeitung
  - Schemavalidierung
  - Qualitätssicherung (PDF-Vergleich)
  - Fehlersuche / Debugging
  - Servermodus
- Kochbuch
  - Griffmarken
  - Mehrseitige PDF-Dateien einbinden
  - Layoutoptimierung mithilfe von Gruppen
  - Verzeichnisse erstellen
  - Seitenzahlen: Seite x von y
  - Aufzählungslisten nachahmen
- Installationsanleitung
- Voreinstellungen im speedata Publisher
- Starten des Publishers über die Kommandozeile
- Konfiguration des Publishers
- Längenangaben und Maßeinheiten
- XPath- und Layoutfunktionen
- Interne Variablen
- Liste der Änderungen
- Glossar
- Befehlsreferenz
  - A
  - Action
  - AddSearchpath
  - AtPageCreation
  - AtPageShipout
  - AttachFile
  - Attribute
  - B
  - Barcode
  - Bold
  - BoldItalic
  - Bookmark
  - Box
  - Br
  - Case
  - Circle
  - Color
  - Column
  - Columns
  - Compatibility
  - Contents
  - Copy-of
  - DefineColor
  - DefineFontalias
  - DefineFontfamily
  - DefineTextformat
  - Element
  - Fontface
  - ForAll
  - Frame
  - Grid
  - Group
  - Groupcontents
  - HSpace
  - Hyphenation
  - I
  - Image
  - Include
  - Initial
  - InsertPages
  - Italic
  - Layout
  - Li
  - LoadDataset
  - LoadFontfile
  - Loop
  - Makeindex
  - Margin
  - Mark
  - Message
  - NewPage
  - NextFrame
  - NextRow
  - NoBreak
  - Ol
  - Options
  - Otherwise
  - Output
  - Overlay
  - Pageformat
  - Pagetype
  - Paragraph
  - PDFOptions
  - PlaceObject
  - Position
  - PositioningArea
  - PositioningFrame
  - ProcessNode
  - Record
  - Regular
  - Rule
  - SaveDataset
  - SavePages
  - SetGrid
  - SetVariable
  - SortSequence
  - Stylesheet
  - Span
  - Sub
  - Sup
  - Switch
  - Table
  - Tablefoot
  - Tablehead
  - Tablerule
  - Td
  - Text
  - Textblock
  - Tr
  - Trace
  - Transformation
  - U
  - Ul
  - Until
  - URL
  - Value
  - VSpace
  - While

# Aufbau der Datendatei und des Layoutregelwerks

> Sie können jedes Datenformat benutzen, solange es XML ist.

— Frei nach Henry Ford

## Datenquelle: XML - wohlgeformt und strukturiert

Die erste Voraussetzung ist, dass die Datenquelle im XML-Format (Extensible Markup Language) vorliegt. Andere Formate werden mit dem Publisher nicht verarbeitet (mithilfe des Lua Filters können auch CSV- und Excel-Dateien verarbeitet werden). In der Praxis spielt das keine Rolle, weil alle (strukturierten) Daten in das XML-Format konvertiert werden können.

Häufig wird gefragt, wie denn das Daten-XML aufgebaut sein muss. Die Antwort darauf ist einfach: es gibt keine Vorgaben, außer dass das XML den üblichen Regeln entsprechen muss (Wohlgeformtheit). Diese Regeln dafür stehen im Glossar.

Daneben gibt es sinnvolle Strukturierungsempfehlungen:

1. Die Daten sollen dann im XML-Baum vorkommen, wenn sie benötigt werden. Datenverarbeitung im Publisher kostet Zeit und Speicher, so dass die Informationen dort vorhanden sein sollten, wo sie benötigt werden. Es gibt natürlich Ausnahmen. Beispielsweise können globale Einstellungen (Farben, zu übersetzende Texte und so weiter) am Anfang der Datei definiert werden.

2. Unterschiedliche Darstellungen (Varianten) müssen anhand der Daten ablesbar sein. Wenn z. B. ein Seitenwechsel bei einer neuen Artikelgruppe (im Produktkatalog) passieren soll, muss in den Daten ein Wechsel der Artikelgruppe erkennbar sein.

3. Die Daten sollten möglichst strukturiert sein. Ein Produktkatalog könnte z. B. Artikelnummer der Form 123-12345 enthalten. Wenn dabei die ersten drei Ziffern die Artikelgruppe darstellen, könnte dies gegebenenfalls mit Regulären Ausdrücken erkannt werden. Einfacher ist es, wenn die Artikelgruppe bereits in der Datenstruktur angelegt ist, so dass es keiner Erkennung bedarf.

Ein einfaches Beispiel für die Anordnung:

    <productdata>
      <globalsettings>
        ...
      </globalsettings>
      <articlegroup name="interior lights" number="123">
        <article number="123-12345">
          <property1>...</property1>
          <property2>...</property2>
        </article>
        <article number="123-12346">
          <property1>...</property1>
          <property2>...</property2>
        </article>
      </articlegroup>
      <articlegroup name="Außenleuchten" number="124">
        <article number="124-23456">
          <property1>...</property1>
          <property2>...</property2>
        </article>
        <article number="124-54321">
          <property1>...</property1>
          <property2>...</property2>
        </article>
      </articlegroup>
    </productdata>

Redundanz schadet hier nicht, im Gegenteil. Da im Beispiel die Artikelgruppe eine eindeutige Ziffernfolge (123 bzw. 124) hat, würde bei den Artikeln die letzten fünf Ziffern ausreichen. Man kann ja die Zahl aus `articlegroup/@number`, `-` und `article/@number` selbst zusammenbauen. Um sich den Schritt zu sparen, speichert man am Artikel einfach die vollständige Nummer.

Um es zusammenzufassen: Wenn Sie die Möglichkeit haben, auf die Strukturierung der Daten Einfluss zu nehmen: speichern Sie lieber zu viele Informationen, als zu wenige. Experimentieren Sie mit der Reihenfolge der Daten, manchmal erleichtert einem die richtige Struktur die Layouterstellung enorm.

## Wie greift man vom Layout auf die Daten zu?

Da die Datendatei beliebig strukturiert sein kann, bedarf es spezieller Befehle, um auf die Daten zugreifen zu können. Diese werden weiter unten und im Anhang bei den XPath-Funktionen beschrieben. Im Folgenden wird von dieser einfachen Datendatei ausgegangen:

    <catalog>
      <article nr="12345" price="99,95" quantity="1">
        <description>Text</description>
        <image mainimage="yes">art12345.pdf</image>
      </article>
      <article nr="56789" price="45,95" quantity="5">
        <description>Text für 56789</description>
        <image>art56789.pdf</image>
      </article>
    </catalog>

Diese Datendatei wird unter dem Namen `data.xml` gespeichert, damit der Publisher sie finden kann.

Die Layout-Datei (Name: `layout.xml`) wird beim Einlesen ausgeführt: alle Befehle mit dem Namen `<Record>` werden für die spätere Verarbeitung gespeichert, alle anderen Befehle haben sofortige Wirkung. D. h. wenn ein Befehl wie `<DefineColor>` auf der obersten Ebene im Layoutregelwerk enthalten ist, wird er ausgeführt, bevor die eigentliche Datenverarbeitung beginnt.

Eine minimale Layoutdatei für oben gezeigte Datenstrukturierung ist:

    <Layout xmlns="urn:speedata.de:2009/publisher/en"
      xmlns:sd="urn:speedata:2009/publisher/functions/en">

      <Record element="catalog">

      </Record>

    </Layout>

Nach dem Aufruf von `sp` passiert nichts: es wird keine Seite erzeugt, kein Fehler ausgegeben, der Publisher beendet sich einfach:

    ...
    Loading layout instructions "/home/example/layout-en.xml"
    Loading data file "/home/example/data.xml"
    Stop processing data
    0 errors occurred
    Duration: 0.158941 seconds
    node_mem_usage=1 glue, 3 glue_spec, 1 dir, 1 user_defined
    luastate_bytes=0

    No pages of output.
    Transcript written on publisher.log.
    Total run time: 209.499431ms

Es wird deswegen keine Seite erzeugt, weil innerhalb des Elements `<Record>` keine weiteren Befehle angegeben wurden, die eine Ausgabe bewirken.

Die für die Verarbeitung notwendige Struktur ist folgende:

    <Layout xmlns="urn:speedata.de:2009/publisher/en"
      xmlns:sd="urn:speedata:2009/publisher/functions/en">

      <Record element="catalog">
        ①
        <ProcessNode select="*"/> ②
        ③
      </Record>

      <Record element="artikel">
        ④
      </Record>

    </Layout>

① Befehle, die vor den ersten Kindelementen ausgeführt werden sollen, z. B. Titelseite oder Inhaltsverzeichnis erzeugen (die Bezeichnung Kindelement bezieht sich auf die Datendatei).

② Hier werden alle Kindelemente einzeln aufgerufen.

③ Befehle für den Abschluss der PDF-Datei

④ Für jedes Kindelement `artikel` werden diese Befehle ausgeführt. Der »Fokus« ist jetzt bei einem Artikel, so dass man auf die Attribute und Kindelemente von Artikel zugreifen kann.

Innerhalb des unteren `<Record>`-Befehls kann man nun auf Kindelemente und Attribute zugreifen. Beispiele:

- `@nr` ergibt im ersten Aufruf die Zeichenkette `12345`, im zweiten Durchlauf `56789`.
- `description` ergibt eine Sequenz mit einem Element, dem Inhalt `Text` (erster Artikel).
- `image/@mainimage` ist im ersten Fall die Zeichenkette `"ja"` (der Inhalt des Attributs `mainimage`), im zweiten Fall die leere Zeichenkette `""`, weil das Attribut dort nicht vorhanden ist.

Die Details hierzu finden sich im Abschnitt über die XPath-Funktionen.

Alternativ zur Vorgehensweise mit `<ProcessNode>` und dem Gegenstück `<Record>` kann auch mit `<ForAll>` auf Kindelemente zugegriffen werden. Das nachfolgende Beispiel erzeugt für jedes Kindelement mit dem Namen `article` eine Tabellenzeile:

    <Layout xmlns="urn:speedata.de:2009/publisher/en"
      xmlns:sd="urn:speedata:2009/publisher/functions/en">

      <Record element="catalog">
        <PlaceObject>
          <Table stretch="max"> ①
            <Tablehead> ②
              <Tr backgroundcolor="gray">
                <Td>
                  <Paragraph><Value>Article number</Value></Paragraph>
                </Td>
                  <Paragraph><Value>Description</Value></Paragraph>
                </Td>
              </Tr>
            </Tablehead>
            <ForAll select="article"> ③
              <Tr>
                <Td>
                  <Paragraph><Value select="@nr"/></Paragraph>
                </Td>
                <Td>
                  <Paragraph><Value select="beschreibung"/></Paragraph>
                </Td>
              </Tr>
            </ForAll>
          </Table>
        </PlaceObject>
      </Record>
    </Layout>

① Es wird eine Tabelle ausgegeben, die sich über die gesamte Breite erstreckt.

② Ein Tabellenkopf hat die Eigenschaft, dass er auf jeder Seite wiederholt wird.

③ Innerhalb des `<ForAll>` kann auf die Attribute und Kindelemente von jedem Artikel zugegriffen werden, genau wie im oberen Beispiel.

Tabellen werden in den Grundlagen (Kapitel Einführung in Tabellen) und ausführlicher in Kapitel 6 behandelt.

- Erstellen eines Layoutregelwerks
- Objekte ausgeben