我在XML元素中有一些数据如下所示:
<item value="category1,category2">Item Name</item>
我感兴趣的是 value 属性。我能够将此属性中包含的数据放入一个如下所示的模板中:
<xsl:template name="RenderValues">
<xsl:param name="ValueList" />
<xsl:value-of select="$ValueList" /> <!-- outputs category1,category2-->
</xsl:template>
我想要做的是以有效的方式处理逗号分隔值。从RenderValues模板中渲染类似下面内容的最佳方法是什么?
<a href="x.asp?item=category1">category1</a>
<a href="x.asp?item=category2">category2</a>
答案 0 :(得分:8)
在XSLT 2.0 / XPath 2.0中使用the standard XPath 2.0 function tokenize() 。
在XSLT 1.0 中,您需要编写递归调用的模板,或者更方便地使用str-split-to-words
的the FXSL library函数/模板。
以下是后者的示例:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common"
>
<!-- -->
<xsl:import href="strSplit-to-Words.xsl"/>
<!-- -->
<xsl:output indent="yes" omit-xml-declaration="yes"/>
<!-- -->
<xsl:template match="/*">
<xsl:variable name="vwordNodes">
<xsl:call-template name="str-split-to-words">
<xsl:with-param name="pStr" select="string(@value)"/>
<xsl:with-param name="pDelimiters"
select="', '"/>
</xsl:call-template>
</xsl:variable>
<!-- -->
<xsl:apply-templates select="ext:node-set($vwordNodes)/*"/>
</xsl:template>
<!-- -->
<xsl:template match="word" priority="10">
<a href="x.asp?item={.}"><xsl:value-of select="."/></a>
</xsl:template>
<!-- -->
</xsl:stylesheet>
在提供的XML文档上应用上述转换时:
<item value="category1,category2">Item Name</item>
生成了想要的结果:
<a href="x.asp?item=category1" xmlns:ext="http://exslt.org/common">category1</a>
<a href="x.asp?item=category2" xmlns:ext="http://exslt.org/common">category2</a>
此模板的pDelimiters
参数允许指定多个分隔符。在上面的示例中,任何分隔字符都可以是逗号,空格或换行符。
答案 1 :(得分:7)
您正在寻找tokenize function:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:str="http://exslt.org/common">
<xsl:template match="/">
<xsl:variable name="sampleString">XML,XSLT,XPath,SVG,XPointer</xsl:variable>
<xsl:for-each select="str:tokenize($sampleString,',')">
<a>
<xsl:attribute name="href">
<xsl:value-of select="str:concat('x.asp?item=', .)" />
</xsl:attribute>
<xsl:value-of select="."/>
</a>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
答案 2 :(得分:2)
这是一个合理的问题,所提供的答案都很好。但是,如果您使用的是XSLT 1.0,并且无法使用扩展功能,则根本无法实现。 XSLT模板生成结果树片段,XSLT只能在节点集上工作。 XSLT中的标记需要递归,这意味着调用模板,这意味着生成一个无法处理的数据结构。
如果此限制适用于您 - 实际上,即使它不适用 - 您应该尽可能通过找到生成XML的人来解决此问题,其内容必须再次解析在DOM已经解析了并让他或她停止之后。在属性中放置多个值是完全错误的。