如何在XSLT1.0中拆分值字符串?

时间:2015-05-06 14:59:09

标签: xslt xslt-1.0

我有一串单个值和范围,我希望将它们拆分并按照单个值(逗号分隔)和范围(逗号分隔)的顺序排列,使用XSLT1.0。我不希望结果是XML节点的形式,我确实希望结果在同一行。我发现Stack Exchange上的现有解决方案可以工作,但它将它们作为XML节点放在不同的行上。

字符串是:

输入:<mark>9, 11, 345-900, 100-200, 1023, 200-400, 99</mark> 期望的输出:9, 11, 1023, 99, 345-900, 100-200, 200-400

代码:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
    <xsl:template match="mark">
        <xsl:call-template name="tokenizeStringWithoutHyphen">
            <xsl:with-param name="list" select="."/>
            <xsl:with-param name="delimiter" select="','"/>
        </xsl:call-template>
        <xsl:call-template name="tokenizeStringWithHyphen">
            <xsl:with-param name="list" select="."/>
            <xsl:with-param name="delimiter" select="','"/>
        </xsl:call-template>
    </xsl:template>
    <!--############################################################-->
    <!--## Template to tokenize strings                           ##-->
    <!--############################################################-->
    <xsl:template name="separatestrings">
        <xsl:param name="list"/>
        <xsl:param name="delimiter"/>

    </xsl:template>
    <xsl:template name="tokenizeStringWithHyphen">
        <!--passed template parameter -->
        <xsl:param name="list"/>
        <xsl:param name="delimiter"/>
        <xsl:choose>
            <xsl:when test="contains($list, $delimiter)">
                <xsl:variable name="stringContainsHyphen" select="contains(substring-before($list,$delimiter),'-')"/>
                <!--<test><xsl:value-of select="$stringContainsHyphen"/></test>-->
                <xsl:choose>
                    <xsl:when test="$stringContainsHyphen = true()">

                            <!-- get everything in front of the first delimiter -->
                            <xsl:value-of select="normalize-space(substring-before($list,$delimiter))"/>

                    </xsl:when>
                </xsl:choose>
                <xsl:call-template name="tokenizeStringWithHyphen">
                    <!-- store anything left in another variable -->
                    <xsl:with-param name="list" select="substring-after($list,$delimiter)"/>
                    <xsl:with-param name="delimiter" select="$delimiter"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:choose>
                    <xsl:when test="$list = ''">
                        <xsl:text/>
                    </xsl:when>
                    <xsl:otherwise>

                            <xsl:value-of select="$list"/>

                    </xsl:otherwise>
                </xsl:choose>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    <xsl:template name="tokenizeStringWithoutHyphen">
        <!--passed template parameter -->
        <xsl:param name="list"/>
        <xsl:param name="delimiter"/>
        <xsl:choose>
            <xsl:when test="contains($list, $delimiter)">
                <xsl:variable name="stringContainsHyphen" select="contains(substring-before($list,$delimiter),'-')"/>
                <!--<test><xsl:value-of select="$stringContainsHyphen"/></test>-->
                <xsl:choose>
                    <xsl:when test="$stringContainsHyphen = false()">
                        <!-- get everything in front of the first delimiter -->
                        <xsl:value-of select="normalize-space(substring-before($list,$delimiter))"/>
                    </xsl:when>
                </xsl:choose>
                <xsl:call-template name="tokenizeStringWithoutHyphen">
                    <!-- store anything left in another variable -->
                    <xsl:with-param name="list" select="substring-after($list,$delimiter)"/>
                    <xsl:with-param name="delimiter" select="$delimiter"/>
                </xsl:call-template>
            </xsl:when>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

1 个答案:

答案 0 :(得分:1)

  

我不希望结果以XML节点的形式出现,我确实希望得到结果   同一条线。

如果要对值进行排序,则必须先将它们标记为节点。然后对节点进行排序,并将它们作为文本值输出回一行:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="mark">
    <xsl:variable name="tokens">
        <xsl:call-template name="tokenize"/>
    </xsl:variable>
    <xsl:for-each select="exsl:node-set($tokens)/token">
        <xsl:sort select="number(contains(., '-'))" data-type="number" order="ascending"/>
        <xsl:value-of select="." />
        <xsl:if test="position()!=last()">
            <xsl:text>, </xsl:text>
        </xsl:if>
    </xsl:for-each>
</xsl:template>

<xsl:template name="tokenize">
    <xsl:param name="text" select="."/>
    <xsl:param name="delimiter" select="', '"/>
    <xsl:choose>
        <xsl:when test="contains($text, $delimiter)">
            <token>
                <xsl:value-of select="substring-before($text, $delimiter)"/>
            </token>
            <!-- recursive call -->
            <xsl:call-template name="tokenize">
                <xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <token>
                <xsl:value-of select="$text"/>
            </token>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

</xsl:stylesheet>
相关问题