Inhalt
Topic:.Xsltpre.
pStyle=std ulStyle=list-closely tableStyle=stdTable
.
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.
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.
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.
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?)
.
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>
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.