在XSL中将元组转换为数字

时间:2014-07-01 20:48:34

标签: xml xslt

我们说我有这个元组列表:

<TupleList>
    <Tuple>1.1.1</Tuple>
    <Tuple>1.1.2</Tuple>
    <Tuple>1.1.3</Tuple>
    <Tuple>1.2.1</Tuple>
    <Tuple>1.2.2.1</Tuple>
    <Tuple>1.2.2.2</Tuple>
    <Tuple>1.2.2.3</Tuple>
    <Tuple>1.2.3</Tuple>
    <Tuple>1.3.1</Tuple>
    <Tuple>1.3.2</Tuple>
    <Tuple>1.3.3</Tuple>
</TupleList>

现在,让我们说我想把每个人都处理成这样的数字:

1001001000
1001002000
1001003000
1002001000
1002002001
1002002002
1002002003
1002003000
1003001000
1003002000
1003003000

在普通的编程语言中,我可能会将每个元组拆分为&#39;。&#39;然后使用返回的最大数组计数来确定我的整体大小。然后我(可能)循环遍历每个元组的每个数字乘以该数字1000 ^(max-p),其中p是我在数组中的当前位置。

所有这一切,我有办法在XSL中做这样的事情吗?不使用C#或任何其他嵌入式语言,因为我不知道与我合作的工具是否会让我。

在没有使用更高级的编程语言的情况下,这甚至可以在直接的XSL中实现吗?

与往常一样,任何和所有线索都非常感激。

1 个答案:

答案 0 :(得分:1)

  

甚至可以在直接XSL中使用

虽然它不是很简单,但考虑到XSLT甚至没有内置求幂,这是可能的。不过,你可以尝试类似的东西:

XSLT 1.0

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

<xsl:variable name="max">
    <xsl:for-each select="/TupleList/Tuple">
        <xsl:sort select="string-length(translate(., '0123456789', ''))" data-type="number" order="descending"/>
        <xsl:if test="position()=1">
            <xsl:value-of select="string-length(translate(., '0123456789', ''))"/>
        </xsl:if>
    </xsl:for-each>
</xsl:variable>

<xsl:template match="/">
    <NumberList>
        <xsl:for-each select="TupleList/Tuple">
            <xsl:call-template name="numerize">
                <xsl:with-param name="text" select="."/>
            </xsl:call-template>
        </xsl:for-each>
    </NumberList>
</xsl:template>

<xsl:template name="numerize">
    <xsl:param name="text"/>
    <xsl:param name="delimiter">.</xsl:param>
    <xsl:param name="position" select="$max"/>
    <xsl:param name="multiplier">
        <xsl:call-template name="power">
            <xsl:with-param name="base" select="1000"/>
            <xsl:with-param name="exponent" select="$position"/>
        </xsl:call-template>
    </xsl:param>
    <xsl:param name="result" select="0"/>
    <xsl:choose>
        <xsl:when test="contains($text, $delimiter)">
            <!-- recursive call -->
            <xsl:call-template name="numerize">
                <xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
                <xsl:with-param name="position" select="$position - 1"/>
                <xsl:with-param name="result" select="$result + substring-before($text, $delimiter) * $multiplier"/>
             </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <number>
                <xsl:value-of select="$result + $text * $multiplier"/>
            </number>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template name="power">
    <xsl:param name="base"/>
    <xsl:param name="exponent"/>
    <xsl:param name="result" select="1"/>
    <xsl:choose>
        <xsl:when test="$exponent = 0">
            <xsl:value-of select="1"/>
        </xsl:when>
        <xsl:when test="$exponent > 1">
            <xsl:call-template name="power">
            <xsl:with-param name="base" select="$base"/>
            <xsl:with-param name="exponent" select="$exponent - 1"/>
            <xsl:with-param name="result" select="$base * $result"/>
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="$base * $result"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

</xsl:stylesheet>

当这应用于以下测试输入时:

<TupleList>
    <Tuple>0</Tuple>
    <Tuple>1</Tuple>
    <Tuple>1.23</Tuple>
    <Tuple>1.23.456</Tuple>
    <Tuple>1.23.456.78</Tuple>
</TupleList>

结果是:

<?xml version="1.0" encoding="UTF-8"?>
<NumberList>
   <number>0</number>
   <number>1000000000</number>
   <number>1023000000</number>
   <number>1023456000</number>
   <number>1023456078</number>
</NumberList>

-
我相信关于元组元素在0..999范围内整数的假设是不言而喻的。