The following code work fine but I want to simplify it. In these example I have 11 currency denominations (I have only included four here to simplify the question) and I would like a way to simplify this code in a way I don't have to repeat the line with thousand or hundred or fifty ... or one
three times. It seems to me it could be done using <xsl:key
but I haven't found the way.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:variable name="test">
<root>
<other1>
</other1>
<currency g="1">
<sth1>A</sth1>
<thousand>1</thousand>
<hundred>2</hundred>
<fifty>4</fifty>
<one>10</one>
<sth2>C</sth2>
</currency>
<currency g="2">
<sth1>A</sth1>
<sth2>C</sth2>
</currency>
<currency g="3">
<sth1>A</sth1>
<thousand>1</thousand>
<hundred>2</hundred>
<fifty>4</fifty>
<one>10</one>
<sth2>C</sth2>
</currency>
<other2>
</other2>
</root>
</xsl:variable>
<xsl:variable xmlns:xalan="http://xml.apache.org/xalan" name="curr" select="xalan:nodeset($test)/root"/>
<xsl:template match="/">
<root>
<xsl:call-template name="currency"/>
</root>
</xsl:template>
<xsl:template name="currency">
<xsl:for-each select="$curr/currency[thousand or hundred or fifty or one]">
<xsl:if test="position() mod 3 = 1">
<xsl:variable name="nextSibling1" select="following-sibling::currency[thousand or hundred or fifty or one][1]"/>
<xsl:variable name="nextSibling2" select="following-sibling::currency[thousand or hundred or fifty or one][2]"/>
<col1>
<xsl:apply-templates select="." mode="total"/>
</col1>
<col2>
<xsl:apply-templates select="$nextSibling1" mode="total"/>
</col2>
<col3>
<xsl:apply-templates select="$nextSibling2" mode="total"/>
</col3>
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template match="currency" mode="total">
<xsl:value-of select="thousand*1000 hundred*100 fifty*50 one"/>
</xsl:template>
<xsl:template match="*"/>
</xsl:stylesheet>
This is the output:
<root>
<col1>1410</col1>
<col2>1410</col2>
<col3/>
</root>
CodePudding user response:
I am still not sure what exactly your code is supposed to accomplish. If you don't want to repeat the [thousand or hundred or fifty or one]
predicate, then maybe try something like
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:variable name="test">
<root>
<other1>
</other1>
<currency g="1">
<sth1>A</sth1>
<thousand>1</thousand>
<hundred>2</hundred>
<fifty>4</fifty>
<one>10</one>
<sth2>C</sth2>
</currency>
<currency g="2">
<sth1>A</sth1>
<sth2>C</sth2>
</currency>
<currency g="3">
<sth1>A</sth1>
<thousand>1</thousand>
<hundred>2</hundred>
<fifty>4</fifty>
<one>10</one>
<sth2>C</sth2>
</currency>
<other2>
</other2>
</root>
</xsl:variable>
<xsl:variable xmlns:xalan="http://xml.apache.org/xalan" name="curr" select="xalan:nodeset($test)/root/currency[thousand or hundred or fifty or one]"/>
<xsl:template match="/">
<root>
<xsl:for-each select="$curr">
<xsl:variable name="i" select="position()" />
<xsl:if test="$i mod 3 = 1">
<col1 >
<xsl:apply-templates select="." mode="total"/>
</col1>
<col2>
<xsl:apply-templates select="$curr[$i 1]" mode="total"/>
</col2>
<col3>
<xsl:apply-templates select="$curr[$i 2]" mode="total"/>
</col3>
</xsl:if>
</xsl:for-each>
</root>
</xsl:template>
<xsl:template match="currency" mode="total">
<xsl:value-of select="thousand*1000 hundred*100 fifty*50 one"/>
</xsl:template>
</xsl:stylesheet>