使用tokenize函数拆分文本

时间:2014-05-08 20:22:15

标签: xml xslt xpath split xslt-2.0

我正在使用XSLT 2.0将XML转换为HTML。我试图在每第6个字符处拆分属性值。

我的源XML看起来像这样:

<item effrg="521529577580620621623624628628631631642645" />

我当前的(失败的XSLT)如下所示:

<xsl:analyze-string regex=".{{6}}" select="item/@effrg">
     <xsl:matching-substring><xsl:value-of select="."/></xsl:matching-substring>
     <xsl:non-matching-substring><xsl:value-of select="."/></xsl:non-matching-substring>
</xsl:analyze-string>

我想要的输出应该是:

521529 577580 620621 623624 628628 631631 642645

我是否在正确的轨道上?有人可以帮忙吗?

4 个答案:

答案 0 :(得分:2)

或者你可以做到

<xsl:for-each-group select="string-to-codepoints($in)" 
                    group-adjacent="(position()-1) idiv 6">
  <xsl:value-of select="codepoints-to-string((current-group(), 20))"/>
</xsl:for-each-group>

答案 1 :(得分:1)

使用substring()表达式中的for生成数字组序列的替代解决方案,然后使用带有空格分隔符的string-join()来生成所需的输出:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output omit-xml-declaration="yes" indent="yes"/>

<xsl:template match="item">
 <xsl:variable name="size" select="6"/>
 <xsl:value-of select="string-join(for $i in 0 to string-length(@effrg) div $size
                                     return substring(@effrg, $i*$size+1, $size),
                                   ' ')"/>
</xsl:template>

</xsl:stylesheet>

答案 2 :(得分:1)

由于用户在评论中询问了Internet Explorer支持,因此XSLT 2.0可能是错误的选择。

这是一个XSLT 1.0解决方案:

<xsl:template name="splitString">
    <xsl:param name="string"/>
    <xsl:param name="size"/>
    <xsl:choose>
        <xsl:when test="string-length($string) > $size">
            <xsl:variable name="rest">
                <xsl:call-template name="splitString">
                    <xsl:with-param name="string" select="substring($string,$size + 1)"/>
                    <xsl:with-param name="size" select="$size"/>
                </xsl:call-template>
            </xsl:variable>
            <xsl:value-of select="concat(substring($string,1,$size),' ',$rest)"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="$string"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

可以像这样调用:

<xsl:call-template name="splitString">
    <xsl:with-param name="string" select="item/@effrg"/>
    <xsl:with-param name="size">6</xsl:with-param>
</xsl:call-template>

同样在XSLT-2.0中使用analyze-string,实际上这已经足够了:

<xsl:analyze-string select="item/@effrg" regex=".{{6}}">
    <xsl:matching-substring><xsl:value-of select=".,''"/></xsl:matching-substring>
</xsl:analyze-string>

答案 3 :(得分:0)

要拆分您提供的源字符串,您可以使用更简单的表达式:

<xsl:value-of select="replace(item/@effrg, '(.{6}){7}', '$1 $2 $3 $4 $5 $6 $7')" />

在您运行<xsl:analyze-string>的上下文中。

使用<xsl:analyze-string>,您可以使用$n获取每个regex-group(n)组。然后,您可以在XSLT中循环连接递归调用模板中的空格。

但是你也可以使用forstring-join在XPath 2.0中更简洁地循环以获得所需的结果:

<xsl:template match="item">
    <xsl:variable name="size" select="floor(string-length(@effrg) div 6)"></xsl:variable>
    <xsl:analyze-string regex="(.{{6}}){{{$size}}}" select="@effrg">
        <xsl:matching-substring>
            <xsl:value-of select="string-join(for $group in 1 to $size return regex-group($group), ' ')"/>
        </xsl:matching-substring>
    </xsl:analyze-string>
</xsl:template>