如何在 XSLT1.0 中拆分值字符串?
How do I split string of values in XSLT1.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>
I don't want the result in form of XML nodes, I do want the result on
the same line.
如果要对值进行排序,必须先将它们标记为节点。然后对节点进行排序并将它们作为文本值输出回一行:
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>
我有一串单一的值和范围,我想使用 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>
I don't want the result in form of XML nodes, I do want the result on the same line.
如果要对值进行排序,必须先将它们标记为节点。然后对节点进行排序并将它们作为文本值输出回一行:
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>