XSLT 2.0 function für Spreadsheetspalten
Holge r
- xsl
0 ThomasM0 Thomas J.S.
Hallo,
ich habe da ein leidiges Problem, was ich schon immer mal in Angriff nehmen wollte. Ziel soll es sein, ein xsl:function zu erstellen, die eine Nummer in eine Spreadsheet Letter Code umwandelt, Also ganz einfach 1 = A, 5 = E; 27 = AA usw. Zur Zeit regele ich das über eine Templatekombination, die zwar ihre Aufgabe erfüllt, aber mir nicht so richtig gefällt und eher auf die schnelle geschrieben wurde. Eher mag ich xf:translate-column-number($ColumnNumber) einfach aufrufen, als die Template kombination. Nur weiss ich nicht so recht wie ich da am besten herangehe unter xslt2.0.
Abfrage erfolgt über:
<xsl:call-template name="translateColumnNumberToColumnLetter">
<xsl:with-param name="currentColumn" select="$ColumnNumber"/>
</xsl:call-template>
<xsl:template name="translateColumnNumberToColumnLetter">
<xsl:param name="currentColumn" select="0"/>
<xsl:param name="FirstLetter" select="0"/>
xsl:choose
<xsl:when test="$FirstLetter < 27">
xsl:choose
<xsl:when test="$currentColumn < 27">
<xsl:call-template name="getColumnLetter">
<xsl:with-param name="FirstLetter" select="$FirstLetter"/>
<xsl:with-param name="SecondLetter" select="$currentColumn"/>
</xsl:call-template>
</xsl:when>
xsl:otherwise
<xsl:call-template name="translateColumnNumberToColumnLetter">
<xsl:with-param name="FirstLetter" select="$FirstLetter + 1"/>
<xsl:with-param name="currentColumn" select="$currentColumn - 26"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
xsl:otherwise
<xsl:value-of select="'only Column to XX supported'"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="getColumnLetter">
<xsl:param name="FirstLetter"/>
<xsl:param name="SecondLetter"/>
<xsl:call-template name="ColumnLetter">
<xsl:with-param name="Number" select="$FirstLetter"/>
</xsl:call-template>
<xsl:call-template name="ColumnLetter">
<xsl:with-param name="Number" select="$SecondLetter"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="ColumnLetter">
<xsl:param name="Number"/>
<xsl:if test="$Number != 0">
<xsl:if test="$Number = 1">
xsl:textA</xsl:text>
</xsl:if>
<xsl:if test="$Number = 2">
xsl:textB</xsl:text>
</xsl:if>
<xsl:if test="$Number = 3">
xsl:textC</xsl:text>
</xsl:if>
<xsl:if test="$Number = 4">
xsl:textD</xsl:text>
</xsl:if>
<xsl:if test="$Number = 5">
xsl:textE</xsl:text>
</xsl:if>
<xsl:if test="$Number = 6">
xsl:textF</xsl:text>
</xsl:if>
<xsl:if test="$Number = 7">
xsl:textG</xsl:text>
</xsl:if>
<xsl:if test="$Number = 8">
xsl:textH</xsl:text>
</xsl:if>
<xsl:if test="$Number = 9">
xsl:textI</xsl:text>
</xsl:if>
<xsl:if test="$Number = 10">
xsl:textJ</xsl:text>
</xsl:if>
<xsl:if test="$Number = 11">
xsl:textK</xsl:text>
</xsl:if>
<xsl:if test="$Number = 12">
xsl:textL</xsl:text>
</xsl:if>
<xsl:if test="$Number = 13">
xsl:textM</xsl:text>
</xsl:if>
<xsl:if test="$Number = 14">
xsl:textN</xsl:text>
</xsl:if>
<xsl:if test="$Number = 15">
xsl:textO</xsl:text>
</xsl:if>
<xsl:if test="$Number = 16">
xsl:textP</xsl:text>
</xsl:if>
<xsl:if test="$Number = 17">
xsl:textQ</xsl:text>
</xsl:if>
<xsl:if test="$Number = 18">
xsl:textR</xsl:text>
</xsl:if>
<xsl:if test="$Number = 19">
xsl:textS</xsl:text>
</xsl:if>
<xsl:if test="$Number = 20">
xsl:textT</xsl:text>
</xsl:if>
<xsl:if test="$Number = 21">
xsl:textU</xsl:text>
</xsl:if>
<xsl:if test="$Number = 22">
xsl:textV</xsl:text>
</xsl:if>
<xsl:if test="$Number = 23">
xsl:textW</xsl:text>
</xsl:if>
<xsl:if test="$Number = 24">
xsl:textX</xsl:text>
</xsl:if>
<xsl:if test="$Number = 25">
xsl:textY</xsl:text>
</xsl:if>
<xsl:if test="$Number = 26">
xsl:textZ</xsl:text>
</xsl:if>
</xsl:if>
</xsl:template>
Hallo Holge r,
Hallo,
ich habe da ein leidiges Problem, was ich schon immer mal in Angriff nehmen wollte. Ziel soll es sein, ein xsl:function zu erstellen, die eine Nummer in eine Spreadsheet Letter Code umwandelt, Also ganz einfach 1 = A, 5 = E; 27 = AA usw.
...
Nur weiss ich nicht so recht wie ich da am besten herangehe unter xslt2.0.
Hier mal ein Versuch:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:my="http://example.org/my">
<!-- globale Variable -->
<xsl:variable name="abisz" select="('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z')"/>
<!-- Testaufrufe -->
<xsl:template match="/">
<xsl:value-of select="my:xyz(5)"/><!-- E -->
<xsl:text> | </xsl:text>
<xsl:value-of select="my:xyz(27)"/><!-- E -->
<xsl:text> | </xsl:text>
<xsl:value-of select="my:xyz(54)"/><!-- AAB -->
</xsl:template>
<!-- die eigentliche Funktion -->
<xsl:function name="my:xyz">
<xsl:param name="z"/>
<xsl:variable name="x" select="$z div 26"/>
<xsl:value-of select="if($x le 1) then $abisz[$z] else $abisz[1]"/>
<xsl:value-of select="if($x gt 1) then my:xyz($z - 26) else()"/>
</xsl:function>
</xsl:stylesheet>
Grüße,
Thomas
<xsl:value-of select="my:xyz(27)"/><!-- E -->
Nur falsch kopiert, hier kommt AA heraus.
Grüße,
Thomas
Perfect! Ich glaube ich muss mich jetzt doch mal in XQuery einarbeiten ;-)
Vielen Dank! H.
Hallo,
ich habe da ein leidiges Problem, was ich schon immer mal in Angriff nehmen wollte. Ziel soll es sein, ein xsl:function zu erstellen, die eine Nummer in eine Spreadsheet Letter Code umwandelt, Also ganz einfach 1 = A, 5 = E; 27 = AA usw.
Hier eine andere Lösung:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:sdml="http://www.selfhtml.org" exclude-result-prefixes="sdml">
<xsl:variable name="spalten">
<xsl:for-each select="1 to 78">
<spalte id="{position()}" />
</xsl:for-each>
</xsl:variable>
<xsl:function name="sdml:createColumLetter">
<xsl:param name="l" />
<xsl:param name="c" />
<xsl:param name="n" />
<xsl:variable name="letters" select="tokenize('A B C D E F G H I J K L M N O P Q R S T U V W X Y Z', ' ')" />
<xsl:sequence select="if(($n div 26) <= 1) then concat($l, $letters[position() = $n]) else sdml:createColumLetter(concat($l, $letters[position() = $c]), ($c + 1), ($n - 26))"></xsl:sequence>
</xsl:function>
<xsl:template match="/">
<xsl:for-each select="$spalten/spalte">
<spalte name="{@id}" id="{sdml:createColumLetter('', 1, @id)}" />
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
das XSL an sich angewendet liefert:
<?xml version="1.0" encoding="UTF-8"?>
<spalte name="1" id="A"/>
...
<spalte name="5" id="E"/>
...
<spalte name="26" id="Z"/>
<spalte name="27" id="AA"/>
...
<spalte name="52" id="AZ"/>
<spalte name="53" id="ABA"/>
...
<spalte name="78" id="ABZ"/>
Grüße
Thomas