Hi,
mein XSLT funktioniert - dank Martin Honnen - soweit ganz gut:
Leider muß ich während der Transformation ab und zu auch noch für eine bestimmte Reihenfolge sorgen. Ich habe versucht in das Container-Template eine Ausfallbehandlung einzufügen:
Das hat natürlich nicht funktioniert.
Die perfekte Lösung wäre vermutlich ein separates Template (ähnlich der Translate-Templates), in dem ich die Spezialfälle sauber auflisten könnte, auch um deren Wartbarkeit zu gewährleisten.
Wenn ich das richtig sehen sollte, müßte dieses separate Template im Container-Element vor der Standard-Behandlung angesiedelt werden, alle betroffenen Elemente enthalten (damit er nicht in eine falsche Rekursion läuft) und die betroffenen Elemente entsprechend transformieren.
Als Quasi-Code also sowas wie "Wenn 'theCode' oder 'tblabc_SenderAddress' oder 'tblabc_DeliveryAddress', dann call-template 'reorder'." - und in diesem Template müßten die Nodes dann ähnlich wie im Container-Element verarbeitet werden.
Das führte zwar zu einer gewissen Duplizierung von XSLT-Code, aber wäre vmtl am zielführendsten.
Sehe ich das richtig? Gibt es ggf einen besseren Weg um das gewünschte Ziel zu erreichen?
mein XSLT funktioniert - dank Martin Honnen - soweit ganz gut:
Code:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:the-abc="https://www.abc.org/the-abc" xmlns:the-gen="https://www.abc.org/the-GEN" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" https://www.abc.org/the-GEN the-gen-1.2.xsd https://www.abc.org/the-abc the-abc-5.1.xsd"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:variable name="Prefix" select="'tblabc_'"/> <xsl:template match="/"> <xsl:apply-templates select="dataroot/tblabc_theabc" mode="root"/> </xsl:template> <!-- Root element --> <xsl:template match="*" mode="root"> <the-abc:theabc xmlns:the-abc="https://www.abc.org/the-abc" xmlns:the-gen="https://www.abc.org/the-GEN" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" https://www.abc.org/the-GEN the-gen-1.2.xsd https://www.abc.org/the-abc the-abc-5.1.xsd"> <xsl:for-each select="child::node()"> <xsl:choose> <!-- Default processing --> <xsl:when test="child::node()/child::node()"> <xsl:apply-templates select="." mode="container"/> </xsl:when> <xsl:otherwise> <xsl:apply-templates select="." mode="element"/> </xsl:otherwise> </xsl:choose> </xsl:for-each> </the-abc:theabc> </xsl:template> <!-- Container element --> <xsl:template match="*" mode="container"> <xsl:variable name="Container"> <xsl:apply-templates select="." mode="translateContainer"/> </xsl:variable> <xsl:if test="not(string-length($Container) = 0)"> <xsl:element name="{$Container}"> <xsl:for-each select="child::node()"> <xsl:choose> <xsl:when test="child::node()/child::node()"> <xsl:choose> <!-- Special containers --> <xsl:when test="local-name() = 'tblabc_SenderAddress'"> <xsl:apply-templates select="." mode="address"/> </xsl:when> <xsl:when test="local-name() = 'tblabc_DeliveryAddress'"> <xsl:apply-templates select="." mode="address"/> </xsl:when> <!-- Default container --> <xsl:otherwise> <xsl:apply-templates select="." mode="container"/> </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:otherwise> <!-- Default element --> <xsl:apply-templates select="." mode="element"/> </xsl:otherwise> </xsl:choose> </xsl:for-each> </xsl:element> </xsl:if> </xsl:template> <!-- Address container --> <xsl:template match="*" mode="address"> <xsl:if test="not(local-name(preceding-sibling::*[1]) = local-name(.))"> <xsl:variable name="Container"> <xsl:apply-templates select="." mode="translateContainer"/> </xsl:variable> <xsl:element name="{$Container}"> <xsl:for-each select="../child::*/child::AddressLine"> <xsl:apply-templates select="." mode="element"/> </xsl:for-each> </xsl:element> </xsl:if> </xsl:template> <!-- Value element --> <xsl:template match="*" mode="element"> <xsl:if test="not(substring-after(local-name(), substring-before(local-name(), 'Id')) = 'Id')"> <xsl:variable name="Element"> <xsl:apply-templates select="." mode="translateElement"/> </xsl:variable> <xsl:if test="not(string-length($Element) = 0)"> <xsl:element name="{$Element}"> <xsl:value-of select="."/> </xsl:element> </xsl:if> </xsl:if> </xsl:template> <!-- ================================================================================ --> <!-- Export from database --> <!-- ================================================================================ --> <!-- Container translation --> <xsl:template match="*" mode="translateContainer"> <xsl:choose> <xsl:when test="local-name() = 'tblabc_theabc'"> <xsl:value-of select="'the-abc:theabc'"/> </xsl:when> </xsl:choose> </xsl:template> <!-- Value element translation --> <xsl:template match="*" mode="translateElement"> <xsl:choose> <xsl:when test="local-name() = 'abcFilePrefix'"> <xsl:value-of select="'the-abc:abcFilePrefix'"/> </xsl:when> </xsl:choose> </xsl:template> </xsl:stylesheet>
Code:
<!-- Special order --> <!-- <xsl:when test="local-name(.) = 'theCode' and local-name(following-sibling::node()) = 'tblabc_SenderAddress'"> <xsl:apply-templates select="following-sibling::node()" mode="address"/> <xsl:apply-templates select="node()" mode="element"/> </xsl:when> <xsl:when test="local-name(.) = 'theCode' and local-name(following-sibling::node()) = 'tblabc_DeliveryAddress'"> <xsl:apply-templates select="following-sibling::node()" mode="address"/> <xsl:apply-templates select="node()" mode="element"/> </xsl:when> -->
Die perfekte Lösung wäre vermutlich ein separates Template (ähnlich der Translate-Templates), in dem ich die Spezialfälle sauber auflisten könnte, auch um deren Wartbarkeit zu gewährleisten.
Wenn ich das richtig sehen sollte, müßte dieses separate Template im Container-Element vor der Standard-Behandlung angesiedelt werden, alle betroffenen Elemente enthalten (damit er nicht in eine falsche Rekursion läuft) und die betroffenen Elemente entsprechend transformieren.
Als Quasi-Code also sowas wie "Wenn 'theCode' oder 'tblabc_SenderAddress' oder 'tblabc_DeliveryAddress', dann call-template 'reorder'." - und in diesem Template müßten die Nodes dann ähnlich wie im Container-Element verarbeitet werden.
Das führte zwar zu einer gewissen Duplizierung von XSLT-Code, aber wäre vmtl am zielführendsten.
Sehe ich das richtig? Gibt es ggf einen besseren Weg um das gewünschte Ziel zu erreichen?