Master Detail Plan

ablauf_planerstellung.png

Plantypen für die Datenbeschaffung

MasterDetailPlan:

  • *.plan.xml
  • Zusammenführung von Daten aus verschiedenen Datenbank-Datenquellen zu einem Ergebnis-XML-Dokument
  • Vorteil gegenüber eine Datenbankabfrage:
    • datenbankübergreifende Abfragen einfach möglich
    • Ergebnis ist eine Baumstruktur und keine Tabelle
    • bessere Lesbarkeit
  • Kann DataExecutionPlan als Unterplan aufrufen
  • Unterstützt Ausgabe in XML, HTML, PDF

DataExecutionPlan:

  • Verknüpfung von Ausführungsschritten, die jeweils wieder als Input eines weiteren Ausführungsschrittes dienen
  • Nutzung von Ebenen als Datenquellen
  • Es stehen grundlegende Geometrieoperationen zur Verfügung

 

Datenbeschaffung über Master-/Detail Dokument

Die eigentliche Datenbeschaffung erfolgt über ein Master-/Detail-Dokument. Die Verarbeitung erfolgt pro Datensatz (nennen wir es hier Dokument) aus dem Hauptdatensatz (Master).

Die "Detail" Elemente können verschachtelt werden. Es gibt abhängige (Dependend) und unabhängige (Independend) Detail-Elemente.

<ButtonMasterDetailDocument xmlns="http://schemas.webs.idu.de/cardo3/Button"             xmlElementName="MASSNAHME">
  <InternalId>5</InternalId>         
  <BaseQuery>             
    SELECT MASZN_NR as Nummer FROM  GW.MASZN_BESCHREIBUNG
  </BaseQuery>         
  <!-- Detail - Datensätze Bilder -->         
  <Detail xmlElementCollectionName="BILDER">
    <Independend xmlElementName="BILD">
      <InternalId>5</InternalId>
      <BaseQuery>                     
        select fileName, untertitel from ...  
      </BaseQuery>
    </Independend>
  </Detail>
  ....
  Filter auf Datenmenge
  ...
</ButtonMasterDetailDocument>

Generiert wird daraus ein XML Dokument, die Elemente entsprechen den Feldnamen. Für Testszwecke kann dieses hier mit der Option "Xml" untransformiert ausgegeben werden.

Das XML Dokument hat immer den Aufbau:   
    ButtonRow
    + ButtonOptions xmlns="http://schemas.webs.idu.de/cardo3/Button
        + ExcecutionPlanOption xmlns=""
        + ExcecutionPlanOption xmlns=""
    + xmlElementName {xmlElementName aus ButtonMasterDetailDocument
        + Detail ...      
--->>> aus beiden zusammen wird bei der Planausführung xml, html und pdf generiert.

Namespaces

case sensitiv!

Standardnamespaces:
xmlns="http://schemas.webs.idu.de/cardo3/Button"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://webs.idu.de/xsdschemas/Cardo/Button/Button.xsd"

weitere Namespaces:

xmlns:iXHR="http://schemas.webs.idu.de/iwan/iXRH"
xsi:schemaLocation="iXRH http://webs.idu.de/xsdschemas/Iwan/iXRH.xsd"

Start mit einem minimalen Plan
<?xml version="1.0" encoding="utf-8"?>
<ExcecutionPlan xmlns="http://schemas.webs.idu.de/cardo3/Button"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://webs.idu.de/xsdschemas/Cardo/Button/Button.xsd">
  <ButtonMasterDetailDocument>    
    <MasterRecord>      
      <DatabaseQuery>        
        <InternalAlias>BUTTON_SCHULUNG</InternalAlias>     
        <BaseQuery>          
          select * from fotos.anwenderfotos        
        </BaseQuery>   
      </DatabaseQuery>    
    </MasterRecord>  
  </ButtonMasterDetailDocument>
</ExcecutionPlan>

 

--> ExecutionPlan: Definition der Schemata, Start der Planausführung

--> ButtonMasterDetailDocument

--> MasterRecord

--> DatabaseQuery

--> InternalAlias: Alias, der bei der Einrichtung der Datenbankverbindung vergeben wurde (siehe folgende Abbildung)

--> BaseQuery: SQL Abfrage

alias.png

Ergebnis XML des minimalen Plans
<ButtonRow>
  <ButtonOptions xmlns="http://schemas.webs.idu.de/cardo3/Button">
    <ButtonEnv xmlns="">
      <Attachments />
      <Variables />
    </ButtonEnv>
  </ButtonOptions>
  <Document>
    <id>20</id>
    <dateiname>LCNLTSJGSTPUQTOWMYWQQSKDI.JPG</dateiname>
    ...
  </Document>
</ButtonRow>
Capabilities - Eigenschaften eines Plans

Festlegung von Parametern, die die Abfrage begrenzen oder hinsichtlich Ausgabeformat konkretisieren. Sie beschreiben die Eigenschaften des Plans und werden von der Oberfläche der Ausführung ausgewertet. Sie werden vor dem ButtonMasterDetailDocument in das xml eingebunden. Dies können sein:

  • Author: Ersteller des Plans
  • Title: Titel, so wie er in der Anwendung angezeigt werden soll (wenn fehlt, wird Dateiname angezeigt)
  • Description: Beschreibung des Plans (z.B. für Webservice, wird in ButtonApp noch nicht angezeigt)
  • Arguments: Startparameter für den Plan
  • Webservice: Aufruf des Plans als Webservice ermöglichen

 

<Capabilities>
  <Author>Stefan Möller</Author>
  <Description>Beispielplan für Button-Schulung</Description>
  <Arguments>
    <Argument name="Format" netTypeName="System.String" restriction="PDF HTML XML" />
  </Arguments>
  <WebService>
    <MethodeName>BeispielPlanSchulungMoeller</MethodeName>
    <EnablePublic>false</EnablePublic>
    <EnableSession>false</EnableSession>
    <BufferResponse>false</BufferResponse>
    <AsmxCodeGeneratorVersion>2</AsmxCodeGeneratorVersion>
  </WebService>
</Capabilities>

 

Erläuterung zum Beispiel

--> Author: Ersteller des Plans

--> Description: Beschreibung des Plans

(weitere Elemente siehe Beschreibung oben)

--> Arguments: Startparameter für den Plan

  • name – Anzeigename für den Parameter
<Arguments>
    <Argument name="Format" netTypeName="System.String" restriction="PDF HTML XML" array="true" />
    Nummer der Maßnahme (bspw. I-047)
  </Arguments>

 

arguments.png

  • netTypeName – Datentyp, daraus wird das Feld in der Eingabemaske generiert
  • nullable – gibt an, ob dieser Parameter optional ist
  • restriction – leerzeichengetrennte Liste zulässiger Werte
  • array- Argument wird als kommaseparierte Liste von Werten erwartet (als Is-Operator dann ‚In‘ verwenden) --> array = "true"
<SingleComparison>
            <ColumnName>id</ColumnName>
            <Is>In</Is>
            <ResultValue>
              <ValueRef key="id"/>              
            </ResultValue>      
          </SingleComparison>

 

arguments2.png

--> Webservice

 

Optionen
  • Diverse Optionen, diese können im Xslt mit ausgewertet werden und spielen für die Ausführung der Datenbeschaffung keine Rolle. Die Definiton hier erfolgt auf Grund der besseren Validierung im Xml und (ein entsprechendes Werkzeug vorausgesetzt) einer vereinfachten Definiton durch Intellisens-Unterstützung.   
  • Die Optionen können im Xslt verwendet werden. Für die Modifikation stehen diverse Methoden im Xslt bereit, die Methoden werden von der Laufzeit als Extension zur Verfügung gestellt.
  • nach der Capabilities Anweisung

Einzubinden im Xslt mit der Deklaration xmlns:cardoButton="eo:cardoButton"

  <Options>
    <Option optionId="RenderOverViewMap">
      <RenderMap xmlns="http://schemas.webs.idu.de/iwan/iXRH"
                 imageHeight="350"
                 imageWidth="400"
                 targetImageType="Png"
                 epsgCode="31469"
                 imageSizeLargestEdge="1000">
        <BBox epsgCode="31469"
              xmin="5398774"
              ymin="5649395"
              xmax="5429208"
              ymax="5672157"
              />
        <!-- die Layer-Liste wird später überschrieben -->
        <Layer layerName="L13"/>
      </RenderMap>
    </Option>
  </Options>
Filter einbinden und erstellen

Hinweis: In XML muss alles als Baum abbildbar sein!

  •  Filter werden im ButtonMasterDetailDocument definiert

filter_01.png

Verknüpfung von Ausdrücken mit AND oder OR

filter_02.png

 

Beispiel:

 

<?xml version="1.0" encoding="utf-8"?>
<ExcecutionPlan xmlns="http://schemas.webs.idu.de/cardo3/Button"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:noNamespaceSchemaLocation="http://webs.idu.de/xsdschemas/Cardo/Button/Button.xsd">
  <Capabilities>
    <Title>Uebung 1</Title>
    <Arguments>
      <Argument name="id" netTypeName="System.Int32" nullable="false">
        ID des Fotos
      </Argument>
    </Arguments>
  </Capabilities>
  <ButtonMasterDetailDocument>
    <MasterRecord xmlElementName="Schild" >
      <DatabaseQuery>
        <InternalAlias>BUTTON_SCHULUNG</InternalAlias>
        <BaseQuery>
          select * from fotos.anwenderfotos
        </BaseQuery>
      </DatabaseQuery>
      <Filter>
        <Filter>
          <SingleComparison>
            <ColumnName>id</ColumnName>
            <Is>Equal</Is>
            <ValueRef key="id"/>
          </SingleComparison>
        </Filter>
      </Filter>
    </MasterRecord>
  </ButtonMasterDetailDocument>
</ExcecutionPlan>
Ergebnis XML mit Filterausdrücken
<ButtonRow>
  <ButtonOptions xmlns="http://schemas.webs.idu.de/cardo3/Button">
    <ButtonEnv xmlns="">
      <Attachments />
      <Variables>
        <Var name="Format" store="Default">PDF</Var>
      </Variables>
    </ButtonEnv>
  </ButtonOptions>
  <Row>
    <id>20</id>
    <dateiname>LCNLTSJGSTPUQTOWMYWQQSKDI.JPG</dateiname>
    <date_time_orig>2014-03-27T13:23:54</date_time_orig>
    <focal_length>25</focal_length>
    ...
  </Row>
</ButtonRow>

 

  • Alle Ergebnisspalten des MasterRecord-BaseQuery werden als Unter-Tags ausgegeben
  • Alle eingegebenen Parameter stehen unter ButtonEnv/Variables zur Verfügung
  • Tag-Standardname ‚Row‘ kann über das Attribut ‚xmlElementName‘ geändert werden

<MasterRecord xmlElementName="Schild">
  <DataExcecutionPlan>
verschachtelte Filterausdrücke

Achtung: linker Wert eines Vergleichs muss immer ein Einzelwert sein, soll z.B. ein Array-Parameter verglichen werden, muss dieser immer auf der rechten Seite des Ausdrucks stehen.

 

filter_03.png

 

Erstellung von Detailplänen
  • ein DetailPlan ist eine Unterabfrage
  • Verbindung wird über Spalten hergestellt
  • Eigenschaft dependent (abhängig von ButtonMasterDetailDocument und independent (keine Verbindung zum Master-Datensatz)  -

    Bei den abhängigen Details wird die Variable %PARENT_ID_VALUE% zur Ersetzung im Sql vom System bereitgestellt

 

detailplan_01.png

Da Verknüpfung 1:n sein kann, immer Collection-Tag (hier Datum) und darin n Element-Tags (hier MassnahmeExposeData)!

detailplan_02.png

Verschneidung mit der Geometrie

Nachfolgend soll gezeigt werden, wie das Planergebnis über eine Verschneidung mit einer vorgegebenen Geometrie (z.B. Freihandgeometrie aus dem GIS-Viewer) ermittelt werden kann.

Definition des Parameters für die Filtergeometrie:

<Arguments>
  <Argument name="Geometrie" netTypeName="IDU.GeoLib.Geometry" nullable="false">Selektionsgebiet</Argument>
</Arguments>

Wird als Datenquelle eine Datenbank-Tabelle mit Geometriespalte verwendet, muss darauf geachtet werden, dass die Geometriespalte in der cardo-Projektprojektion vorliegt oder gegebenenfalls in diese Projektion transformiert wird.

Beispiel:

<ButtonMasterDetailDocument>
  <MasterRecord xmlElementName="Blattschnitt">
    <DatabaseQuery>
      <InternalAlias>moe_cardo_db</InternalAlias>
      <BaseQuery>
        SELECT ST_Transform(ST_SetSRID(geom,31468),31469) AS geom
                FROM km_meta.bl25_sa
      </BaseQuery>
    </DatabaseQuery>
    <Filter>
      <Filter>
        <SingleGeomComparison >
          <ColumnName>geom</ColumnName>
          <Is>DefaultRelateT8Stars</Is>
          <ValueRef key="Geometrie" />
        </SingleGeomComparison>
      </Filter>
    </Filter>
  </MasterRecord>
</ButtonMasterDetailDocument>

 

Erläuterung:

Im Beispiel (Postgres) liegt die Geometriespalte der Tabelle km_meta.bl25_sa in GK4 vor, die cardo-Projektion ist aber auf GK5 eingestellt. Deswegen wird hier die Spalte vor der Abarbeitung des Plans explizit in die cardo-Projektion transformiert. Das ist nötig, da aus der Geomtriespalte der Datenbank die Projektion nicht eindeutig ermittelt werden kann und damit keine automatische Transformation erfolgen kann.

Verwenden Sie als Datenquelle eine cardo-Ebene, dann ist die Projektion bekannt und es findet gegebenenfalls eine automatische Transformation statt.

  • T8Stars = T******** à Prüfung auf  Interior-Bezug zwischen den Geometrien
  • Erkennung der gängigen String-Geometrierepräsentationen wie IWAN-Geom oder WKT
Beispiel DetailPlan
  • Nutzer gibt Geometrie vor (Definition über das Argument)
  • Filter mit der Nutzergeometrie auf die Tabelle fotos.anwenderfotos

--> gibt alle Fotos zurück, die innerhalb der definierten Geometrie liegen

Hinweis: Filter immer nach den Detail Plänen

  • zusätzlich wird über einen Detailplan die Tabelle naturschutz.nso_festgesetzt mit der Tabelle fotos.anwenderfotos über die Spalten Thema und Bezeichnung verknüpft
  • über einen weiteren Detailplan werden alle Fotos ausgegeben, die zusätzlich innerhalb der Geometrie der Trinkwasserschutzgebiete liegen

--> Rückgabe aller Fotos innerhalb der Nutzergeometrie, die im Naturschutzgebiet und zusätzlich im Trinkwasserschutzgebiet liegen

 

<?xml version="1.0" encoding="utf-8"?>
<ExcecutionPlan xmlns="http://schemas.webs.idu.de/cardo3/Button"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:noNamespaceSchemaLocation="http://webs.idu.de/xsdschemas/Cardo/Button/Button.xsd"   >
  <Capabilities>
    <Title>Übung 3a</Title>
    <Arguments>
      <Argument name="Geometrie" netTypeName="IDU.GeoLib.Geometry" nullable="false">Geometrie des Naturschutzgebietes</Argument>
    </Arguments>
  </Capabilities>
  <ButtonMasterDetailDocument>
    <MasterRecord xmlElementName="Schild" >
      <DatabaseQuery>
        <InternalAlias>BUTTON_SCHULUNG</InternalAlias>
        <BaseQuery>
          select * from fotos.anwenderfotos
        </BaseQuery>
      </DatabaseQuery>
      <Detail>
        <Dependend parentColumnName="Thema" referenceColumnName="Bezeichnung" xmlElementName="Naturschutzgebiet">
          <DatabaseQuery>
            <InternalAlias>BUTTON_SCHULUNG</InternalAlias>
            <!--Verknüpfung der Tabellen fotos.anwenderfotos und naturschutz.nso_festgesetzt über die Spalten Thema und Bezeichnung-->
            <!--gibt alle Fotos wieder, die im Naturschutzgebiet liegen-->
            <BaseQuery>
              select * from naturschutz.nso_festgesetzt
            </BaseQuery>
          </DatabaseQuery>
        </Dependend>
      </Detail>
      <Detail >
        <!--gibt alle Fotos wieder die innerhalb des Trinkwasserschutzgebietes liegen und die innerhalb der eingegebenen Nutzergeometrie liegen-->
        <Complex xmlElementName="Trinkwasserschutzgebiet">
          <DatabaseQuery>
            <InternalAlias>NOS_HERMES</InternalAlias>
            <BaseQuery>
              select * from km_meta.exd_admtreeid_1342
            </BaseQuery>
          </DatabaseQuery>
          <Filter>
            <Filter>
              <SingleGeomComparison>
                <ColumnName>geom</ColumnName>
                <Is>DefaultRelateT8Stars</Is>
                <ResultValue>
                  <Result columnName="the_geom"/>
                </ResultValue>
              </SingleGeomComparison>
            </Filter>
          </Filter>
        </Complex>
      </Detail>
      <!--Nutzereingabe der Geometrie in der Button Anwenderoberfläche, immer nach den Detail Plänen-->
      <Filter>
        <Filter>
          <SingleGeomComparison>
            <ColumnName>the_geom</ColumnName>
            <Is>DefaultRelateT8Stars</Is>
            <ValueRef key="Geometrie"/>
          </SingleGeomComparison>
        </Filter>
      </Filter>
    </MasterRecord>
  </ButtonMasterDetailDocument>
</ExcecutionPlan>
DetailPlan mit eigener Datenquelle
  • Voraussetzung:Definition der neuen Datenquelle als cardo-Datenbankverbindung
  • Referenz auf diese Datenquelle über die interne ID

detailplan_03.png

DataExecutionPlan

DataExecutionPlan:

  • Beschreibt eine Kette von Bearbeitungsschritten für die Datenbeschaffung
  • beschreibt einen Datenbeschaffungsplan
  • Ergebnis ist immer ein System.Data.IDataReader

Prozessor

  • fügt weitere Spalten an die Ausgabe des eingehenden Datenstromes an
  • es werden die Spalten der Datenquelle weitergereicht und um die berechnenden ergänzt

dataexecutionplan.png

 

Zwischentabellen:

dataexecutionplan_01.png

Beispiel Plan aus mehreren Ebenen

Ergebnis: Erstellung eines Datenblattes zu einem Radweg, auf welchem neben den Daten zum Radweg auch alle Ärzte in einem bestimmten Umkreis, alle LSG’s, welche berührt werden und die Teillänge des Radweges, welche durch die LSG führt, ausgegeben wird.

Die Kommentare entnehmen Sie bitte dem Beispiel XML.

<?xml version="1.0" encoding="utf-8"?>
<ExcecutionPlan xmlns="http://schemas.webs.idu.de/cardo3/Button"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:noNamespaceSchemaLocation="http://webs.idu.de/xsdschemas/Cardo/Button/Button.xsd" >
  <Capabilities>
    <Title>Übung 5 Radwege</Title>
    <Arguments>
      <Argument name="Radweg" netTypeName="System.String" nullable="false">Radwegname</Argument>
      <Argument name ="Puffer" netTypeName="System.Int32" nullable="false">Puffer um Radweg</Argument>
      <Argument name="Format" netTypeName="System.String" nullable="false" restriction="PDF HTML XML">Format</Argument>
      <Argument name ="Groesse" netTypeName="System.String" nullable="true" restriction="A4 A3 A2" >Größe</Argument>
    </Arguments>
  </Capabilities>
  <ButtonMasterDetailDocument>
    <MasterRecord xmlElementName="Radweg">
      <DataExcecutionPlan>
        <Processor>
          <!--neue Spalte hinzufügen mit der Länge des Radweges-->
          <Length>
            <ColumnName alias="LaengeRadweg">geom</ColumnName>
          </Length>
        </Processor>
        <OperatesOn>
          <!--sucht aus der Eben NOS_RADWEGE die, die mit der Bezeichnung aus dem Argument Radweg übereinstimmen-->
          <Filter>
            <SingleComparison compareBehavior="CompareStringsCaseInSensitiv">
              <ColumnName>bezeichnung</ColumnName>
              <Is>Like</Is>
              <ResultValue>
                <StringFormat>
                  <Format>%{0}%</Format>
                  <Arg>
                    <Var key="Radweg"/>
                  </Arg>
                </StringFormat>
              </ResultValue>
            </SingleComparison>
          </Filter>
          <OperatesOn>
            <!--Auswahl der Ebene-->
            <LayerDatasource>
              <LayerAlias>NOS_RADWEGE</LayerAlias>
            </LayerDatasource>
          </OperatesOn>
        </OperatesOn>
      </DataExcecutionPlan>
      <Detail>
        <Complex xmlElementName="Ärzte">
          <DataExcecutionPlan>
            <!--sucht alle Ärzte aus der Ebene NOS_AERZTE innerhalb des Puffers-->
            <Filter>
              <SingleComparison>
                <ColumnName>Distanz</ColumnName>
                <Is>LessEqual</Is>
                <ValueRef key="Puffer"/>
              </SingleComparison>
            </Filter>
            <OperatesOn>
              <Processor>
                <!--ermittelt die Distanz der Ärzte zum Radweg-->
                <Distance>
                  <ColumnName alias="Distanz">geom</ColumnName>
                  <To>
                    <!--Spalte Geom aus NOS_Radwege-->
                    <Result columnName="geom"/>
                  </To>
                </Distance>
              </Processor>
              <OperatesOn>
                <LayerDatasource>
                  <LayerAlias>NOS_AERZTE</LayerAlias>
                </LayerDatasource>
              </OperatesOn>
            </OperatesOn>
          </DataExcecutionPlan>
        </Complex>
      </Detail>
      <Detail>
        <!--ermittelt die Landschaftsschutzgebiete die vom Radweg geschnitten werden-->
        <Complex xmlElementName="Landschaftsschutzgebiete">
          <DataExcecutionPlan>
            <Filter>
              <SingleGeomComparison>
                <ColumnName>geom</ColumnName>
                <Is>DefaultRelateT8Stars</Is>
                <ResultValue>
                  <Result columnName="geom"/>
                </ResultValue>
              </SingleGeomComparison>
            </Filter>
            <OperatesOn>
              <Processor>
                <!--hängt zwei neue Spalten an-->
                <Length>
                  <ColumnName alias="schneidet">schneidet</ColumnName>
                </Length>
                <Buffer>
                  <!--erstellt einen Puffer um den Radweg-->
                  <ColumnName alias="Radweg_gepuffert">schneidet</ColumnName>
                  <Distance>
                    <Literal>
                      <Double>0.000001</Double>
                    </Literal>
                  </Distance>
                </Buffer>
              </Processor>
              <OperatesOn>
                <Processor>
                  <Intersection>
                    <ColumnName alias="schneidet">geom</ColumnName>
                    <With>
                      <!--Spalte geom aus NOS_Radwege-->
                      <Result columnName="geom"/>
                    </With>
                  </Intersection>
                </Processor>
                <OperatesOn>
                  <!--Zugriff auf Ebene LSG-->
                  <LayerDatasource>
                    <LayerAlias>NOS_LSG</LayerAlias>
                  </LayerDatasource>
                </OperatesOn>
              </OperatesOn>
            </OperatesOn>
          </DataExcecutionPlan>
        </Complex>
      </Detail>
    </MasterRecord>
  </ButtonMasterDetailDocument>
  <PerRowProcess>
    <Html>
      <Condition>
        <SingleComparison>
          <ValueRef key="Format"/>
          <Is>Equal</Is>
          <Value type="System.String">HTML</Value>
        </SingleComparison>
      </Condition>
    </Html>
    <Pdf>
      <Condition>
        <SingleComparison>
          <ValueRef key="Format"/>
          <Is>Equal</Is>
          <Value type="System.String">PDF</Value>
        </SingleComparison>
      </Condition>
      <WellknownPageSize>A4</WellknownPageSize>
      <MarginMm>10</MarginMm>
    </Pdf>
    <XsltFileName>
      <Literal>
        <String>Radwege.xslt</String>
      </Literal>
    </XsltFileName>
  </PerRowProcess>
</ExcecutionPlan>

 

Ergebnis XML:

ergebnisXML.png

 

PDF Layout

Angaben zum Layout direkt im Buttonplan:

<PerRowProcess>
    <Pdf Orientation="Portrait">
        <WellknownPageSize>A4</WellknownPageSize>
        <MarginMm>20</MarginMm>
    </Pdf>
    <XsltFileName>
        <Literal>
            <String>testplan.xslt</String>
        </Literal>
    </XsltFileName>
</PerRowProcess>

Am Pdf-Tag kann als Attribut die Orientierung und als Untertags die Papiergröße (WellKnownPageSize) und Seitenrand (MarginMm mit einem Wert für alle Seiten oder Margins mit Attributen für jede Seite) angegeben werden. Soll die Papiergröße frei definiert werden, kann diese über den Tag PageSize mit Breiten- und Höhenangabe definiert werden.

<PageSize heightMm="300" widhtMm="200"/>

Allerdings ist es nicht möglich, hier auf die vom Benutzer abgefragten Argumente zuzugreifen, so dass die Auswahl von Orientierung und Format an dieser Stelle nicht dynamisch erfolgen können. Um dies zu erreichen können die Erweiterungsfunktionen aus eo:iduPdf verwendet werden. In der Transformation besteht über das Ergebnis-XML Zugriff auf die vom Benutzer abgefragten Argumente.