循环数来获取序列

时间:2017-02-17 13:01:12

标签: xslt xslt-2.0

输入XML:

            <root>
                <number>4</number>
                <format>start1</format>
                <!--this could be start0/start1/alpha   -->
            </root>

我的输出应该是:

如果format = start1打印1,2,3,4

如果format = start0打印0,1,2,3

如果格式= alpha打印A,B,C,D

连续项的数量等于“数”节点的值

XSLT存根:

                 <xsl:template match="/">
                    <xsl:variable name="mynumber" select="number"></xsl:variable>
                    <xsl:variable name="mysequence">
                        <xsl:choose>
                            <xsl:when test="format='start0'">
                                <xsl:for-each select="$mynumber">
                                <!--0,1,2,3-->
                                </xsl:for-each>
                            </xsl:when>
                            <xsl:when test="format='start1'">
                                <xsl:for-each select="$mynumber">
                                <!--1,2,3,4-->
                                </xsl:for-each>
                            </xsl:when>
                            <xsl:when test="format='alpha'">
                                <xsl:for-each select="$mynumber">
                                <!--A, B, C, D-->
                                </xsl:for-each>                    
                            </xsl:when>
                        </xsl:choose>
                    </xsl:variable>
                    <xsl:value-of select="$mysequence"></xsl:value-of>        
                </xsl:template>

2 个答案:

答案 0 :(得分:2)

考虑以下示例:

<强> XML

<root>
    <item>
        <number>4</number>
        <format>start0</format>
    </item>
    <item>
        <number>4</number>
        <format>start1</format>
    </item>
    <item>
        <number>4</number>
        <format>alpha</format>
    </item>
</root>

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="item">
    <sequence>
        <xsl:choose>
            <xsl:when test="format='start0'">
                <xsl:value-of select="for $i in 1 to number return $i - 1" separator=", "/>
            </xsl:when>
            <xsl:when test="format='start1'">
                <xsl:value-of select="for $i in 1 to number return $i" separator=", "/>
            </xsl:when>
            <xsl:when test="format='alpha'">
                <xsl:value-of select="for $i in 1 to number return codepoints-to-string($i + 64)" separator=", "/>
            </xsl:when>
        </xsl:choose>
    </sequence>
</xsl:template>

</xsl:stylesheet>

<强>结果

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <sequence>0, 1, 2, 3</sequence>
   <sequence>1, 2, 3, 4</sequence>
   <sequence>A, B, C, D</sequence>
</root>

请注意,这假定number不会超过26(至少不是format为“alpha”时);否则你需要使用xsl:number将其格式化为alpha格式,如@potame的答案所示 - 除非它更简洁:

<xsl:template match="item">
    <xsl:variable name="fmt" select="format" />
    <sequence>
        <xsl:for-each select="1 to number">
             <xsl:number value="if ($fmt='start0') then . - 1 else ." format="{if ($fmt='alpha') then 'A' else '0'}"/>
             <xsl:if test="position()!=last()">
                <xsl:text>, </xsl:text>
             </xsl:if>
        </xsl:for-each>
    </sequence>
</xsl:template>

答案 1 :(得分:1)

这是一个可能的解决方案,这要归功于使用XPath sequence,例如select="1 to 10"

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output method="html" doctype-public="XSLT-compat"
        omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />

    <xsl:template match="root">
        <xsl:variable name="mynumber" select="number" as="xs:integer" />
        <xsl:variable name="mysequence">
            <xsl:choose>
                <xsl:when test="format='start0'">
                    <xsl:for-each select="0 to ($mynumber - 1)">
                        <!--0,1,2,3-->
                        <xsl:value-of select="."/>
                    </xsl:for-each>
                </xsl:when>
                <xsl:when test="format='start1'">
                    <xsl:for-each select="1 to $mynumber">
                        <!--0,1,2,3-->
                        <xsl:value-of select="."/>
                    </xsl:for-each>
                </xsl:when>
                <xsl:when test="format='alpha'">
                    <xsl:for-each select="1 to $mynumber">
                        <xsl:number value="." format="A"/>
                    </xsl:for-each>                    
                </xsl:when>
            </xsl:choose>
        </xsl:variable>
        <xsl:value-of select="$mysequence"/>        
    </xsl:template>
</xsl:transform>