vishia - Präprozessor für XSL, Kurzschreibweise in XSL

vishia - Präprozessor für XSL, Kurzschreibweise in XSL

Inhalt


Topic:.Xsltpre.

pStyle=std ulStyle=list-closely tableStyle=stdTable

.


1 Motivation

Topic:.Xsltpre..

pStyle=std ulStyle=list-closely tableStyle=stdTable

XSL ist als Konvertierungsscriptsprache für viele Fälle geeignet. Insbesondere zur Erzeugung von textuellen Outputs ist es jedoch durchaus als kryptisch empfindbar. Wenn über Xslt ein textueller Quelltext erzeugt werden soll, dann ist es günstig, alle Bestandteile, die im output in einer Zeile erscheinen sollen, auch im Xsl in einer Zeile zu schreiben. Soll diese Zeile aber viele Bestandteile aus dem Input-Xml beinhalten, dann wird die Zeile relativ lang und unleserlich. Als Beipiel soll eine Zeile aus CHeader2XmlBinCodeElement_Java.xsl dienen. Das Script generiert ein Java-Quellcode aus einem geparsten Headerfile, mit dieser Zeile soll ein Attribut definiert werden, mit dem eine eingebettete Struktur verwaltet wird. Im Xsl original sieht die Zeile wie folgt aus:

 public final </xsl:text><xsl:value-of select="type/@name" /><xsl:text> </xsl:text><xsl:value-of select="@name" /><xsl:text> = new </xsl:text><xsl:value-of select="type/@name" /><xsl:text>(this, kIdx</xsl:text><xsl:value-of select="@name" /><xsl:text>);  //embedded structure

Mit dem Xsl-Präprozessor kann man im Script CHeader2XmlBinCodeElement_Java.xslp kürzer notierten:

 public final (?!type/@name?) (?@name?) = new (?!type/@name?)(this, kIdx(?@name?));  //embedded structure

Die obige Zeile ist output aus der Xsltpre-Übersetzung, müsste aber sonst mit Hand in etwa so geschrieben werden wie gezeigt. Man könnte sich die Einbettung in <xsl:text>...</xsl:text> sparen, das ist aber teilweise auch ungünstig, Leerzeichen sind dann nicht ordentlich formulierbar. Man könnte im XSL-Script das ganze auch mehrzeilig schreiben zwecks überschaubarkeit im XSL, aber dann ist die Erscheinungsform im output nur noch schlecht erkennbar. Die Xsltpre-Übersetzung schafft damit deutliche Abhilfe.


2 Aufruf

Topic:.Xsltpre..

pStyle=std ulStyle=list-closely tableStyle=stdTable

Der XSL-Präprozessor Xsltpre führt lediglich eine einfache textuelle Umsetzung aus (wie suchen und ersetzen). Komplexe Verarbeitungen stecken nicht dahinter. Daher kann ein XSL-Script vor Präprozessoring fast wie ein 'normales' XSL-Script geschrieben und gelesen werden. Als File-extension wird bei vishia .xslp benutzt. Arbeiteet man beispielsweise in Eclipse, kann man das pluging XMLBuddy http://www.xmlbuddy.com/ mit der extension .xslp verbinden und die Files genauso wie XSL bearbeiten. Grundsätzlich werden nur Bereichen zwischen <xsl:text>...</xsl:text> behandelt.

Der Xsltpre-Präprozessor ist in Java geschrieben und wie folgt aufrufbar:

 java -cp zbnf.jar;zmake.jar org.vishia.xmlSimple.Xsltpre -i:xslscript.xslp -o:gen/xslscript.xsl

Die beiden angegebenen jars sind im Download entweder in ZBNF_bei_Sourceforge enthalten oder aus der vishia_Downloadpage beziehbar. Die Sources sind ebenfalls über die vishia_Downloadpage ladbar, siehe auch javadoc:_org/vishia/xmlSimple/Xsltpre.

Die Konvertierung von xslp nach xsl kann aber auch innerhalb eines ANT-Scripts aufgerufen über Zmake erfolgen. Bei der vishia-XML-Dokumentengenerierung erfolgt praktischerweise die xslp-xsl-Konvertierung innerhalb des ANT-Script für das betreffende Dokument, das xsl-Script wird im tmp-Verzeichnis gespeichert. Vorteil: Man kann im xslp editieren, und braucht sich nicht um den Konvertierungsschritt zu kümmern. Ein Zmake/Ant-Aufruf für alle *.xslp sind aber auch zentral ausgeführt im batch Xml_Toolbase/make/makeXsl_fromXslp.bat.


3 Schreibweise im XSL-Script

Topic:.Xsltpre..

pStyle=std ulStyle=list-closely tableStyle=stdTable

Die Erweiterungen sind im XSL-Script grundsätzlich nur in <xsl:text>...</xsl:text> eingebettet und in der Form (?...?) notiert. Damit soll ein Konflikt mit anderen Schreib-Notwendigkeiten vermieden werden. In Programmiersprachen ist die Kombination (? und ?) nicht üblich, daher als Sonderkennzeichnung geeignet.


3.1 xsl:value-of

Topic:.Xsltpre...

pStyle=std ulStyle=list-closely tableStyle=stdTable

(?@attribute?)

Text (Wert) eines Attributes des aktuellen XML-Nodes

wird expandiert nach </xsl:text><xsl:value-of select="@attribute" /><xsl:text>

(?$variable?)

Text (Wert) einer Variable

wird expandiert nach </xsl:text><xsl:value-of select="$variable" /><xsl:text>

(?!path?)

Text (Wert) des selektierten Elementes mit dem angegebenen Path. path ist ein beliebiger XPATH-Ausdruck.

wird expandiert nach </xsl:text><xsl:value-of select="path" /><xsl:text>. Das ist der allgemeine Fall, die Schreibweisen (?@attribute?) (?$variable?) sind also eine Kurzschreibweise von (?!@attribute?) bzw. (?!$variable?).


3.2 if/choose when

Topic:.Xsltpre...

pStyle=std ulStyle=list-closely tableStyle=stdTable

(?if "condition"?)TEXT(?/if?)

Bedingte Erzeugung des dazwischenliegenden TEXT. TEXT kann wieder beliebige (?...?) enthalten. condition ist eine XPATH-condition.

wird expandiert nach </xsl:text><xsl:choose><xsl:when test="condition"><xsl:text>TEXT</xsl:text></xsl:when></xsl:choose><xsl:text>

<xsl:choose> statt <xsl:if> wird benutzt, weil die komplexeren if-Konstrukte <xsl:choose> erfordern.

Die "condition" lässt sich auch ohne "" schreiben.

(?if condition?)TEXT(?else?)TEXT_ELSE(?/else?)

Bedingte alternative Erzeugung des dazwischenliegenden TEXT. TEXT kann wieder beliebige (?...?) enthalten. condition ist eine XPATH-condition

wird expandiert nach </xsl:text><xsl:choose><xsl:when test="condition"> <xsl:text>TEXT</xsl:text> </xsl:when> <xsl:otherwise> <xsl:text>TEXT_ELSE</xsl:otherwise> </xsl:choose> <xsl:text>

Hier zeigt sich die wesentlich einfachere Schreibweise, wenn man eine Alternative braucht. Wichtig ist, dass als Abschluss hier(?/else?) benötigt wird.

(?if condition?)TEXT(?elif condition_2?)TEXT_2(?else?)TEXT_ELSE(?/else?)

Bedingte alternative Erzeugung des dazwischenliegenden TEXT. Es kann beliebig viele Alternativen (?elif...?) geben. (?else?) ist optional.

wird expandiert nach </xsl:text><xsl:choose><xsl:when test="condition"> <xsl:text>TEXT</xsl:text> </xsl:when> <xsl:when test="condition_2"> <xsl:text>TEXT_2</xsl:text> </xsl:when> <xsl:otherwise> <xsl:text>TEXT_ELSE</xsl:otherwise> </xsl:choose> <xsl:text>

Es kann sein, dass bei sehr vielen Alternativen die originale XSLT-Schreibweise doch übersichtlicher ist. Insbesondere bei mehrzeiliger Schreibweise. Diese Konstruktution wird dann eher besser sein, wenn die auszuwählenden Texte relativ kurz sind, also alles übersichtich lesbar ist. Ein Beispiel dafür ist folgende Zeile:

<xsl:text>(?if "accessType='return'"?)(?$Type?)(?elif "accessType='bool'"?)bool(?else?)void(?/else?)</xsl:text>


3.3 call template

Topic:.Xsltpre...

pStyle=std ulStyle=list-closely tableStyle=stdTable

(?call templateName()?)

Das ist ein einfacher Aufruf eines benannten Templates.

wird expandiert nach </xsl:text><xsl:call-template name="templateName" /><xsl:text>.

(?call templateName(parameter="xpath", parameter2="xpath2")?)

Das ist ein Aufruf eines benannten Templates mit Parametern.

wird expandiert nach </xsl:text><xsl:call-template name="templateName" > <xsl:with-param name="paramter" select="path"> <xsl:with-param name="paramter2" select="path2"> <xsl:text>.

Für die Werte der Parameter ist nur eine XPATH-Angabe vorgesehen, die bei select="..." eingetragen wird. Konstante Texte sind wie bei XPATH üblich in 'Hochkommata' angebbar. Komplex zusammengesetzte Parameter sind hier nicht angebbar. Das würde die angestrebte Kurzschreibweise sprengen. Man sollte dies nicht als Einschränkung empfinden, da nicht ein vollständiges anderes XSLT hier angestrebt wird sondern eben nur eine Kurzschreibweise für typische Fälle.

(?call templateName:"pathNode"()?)

Das ist ein Aufruf eines benannten Templates mit Parametern mit voriger Selektion einer bestimmten Xml-Node. pathNode ist ein XPATH-Ausdruck.

wird expandiert nach </xsl:text><xsl:for-each select="pathNode"> <xsl:call-template name="templateName"> </xsl:call-template> </xsl:for-each> <xsl:text>.

(?call templateName:"pathNode"(parameter="xpath", parameter2="xpath2")?)

Das ist nundie 'Vollversion' eines call mit voriger Selektion einer node und Aufrufparametern. Die Notwendigkeit der Einbettung des Aufrufes von benannten Templates ist durchaus häufig gegeben. Damit kann eine Zeichenkette passend funktional komplex zusammengesetzt werden.