下面有两个变量,它们在不同的XSLT变量中有多个逗号分隔的字符串值
Variable_01 : 88888,777777
Variable_02 : abc,xyz
现在我正在寻找以下输出
[{"Group":"88888", "Name":"abc"},{"Group":"777777", "Name":"xyz"}]
能否请您帮我看看以上输出的正确XSLT代码是什么。
答案 0 :(得分:1)
这是一种查看方式:
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:variable name="Variable_01">88888,777777</xsl:variable>
<xsl:variable name="Variable_02">abc,xyz</xsl:variable>
<xsl:template match="/">
<xsl:text>[</xsl:text>
<xsl:for-each select="tokenize($Variable_01, ',')">
<xsl:variable name="i" select="position()"/>
<xsl:text>{"Group":"</xsl:text>
<xsl:value-of select="." />
<xsl:text>", "Name":"</xsl:text>
<xsl:value-of select="tokenize($Variable_02, ',')[$i]" />
<xsl:text>"}</xsl:text>
<xsl:if test="position()!=last()">
<xsl:text>,</xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:text>]</xsl:text>
</xsl:template>
</xsl:stylesheet>
结果
[{"Group":"88888", "Name":"abc"},{"Group":"777777", "Name":"xyz"}]
答案 1 :(得分:0)
在具有高阶函数for-each-pair
且支持JSON映射和数组的XSLT 3中,这就像
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
xmlns:array="http://www.w3.org/2005/xpath-functions/array"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="#all"
version="3.0">
<xsl:output method="json" indent="yes"/>
<xsl:param name="Variable_01" as="xs:string">88888,777777</xsl:param>
<xsl:param name="Variable_02" as="xs:string">abc,xyz</xsl:param>
<xsl:template match="/" name="xsl:initial-template">
<xsl:sequence
select="array {
for-each-pair(
tokenize($Variable_01, ','),
tokenize($Variable_02, ','),
function($a, $b) { map { 'Group' : $a, 'Name' : $b } }
)
}"/>
</xsl:template>
</xsl:stylesheet>
在不支持for-each-pair
的高阶功能的XSLT 3中,您可以按照定义的方式实现自己的功能:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
xmlns:array="http://www.w3.org/2005/xpath-functions/array"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="#all"
version="3.0">
<xsl:output method="json" indent="yes"/>
<xsl:function name="mf:object-for-each-pair" as="map(xs:string, xs:string)*">
<xsl:param name="seq1"/>
<xsl:param name="seq2"/>
<xsl:param name="action"/>
<xsl:if test="exists($seq1) and exists($seq2)">
<xsl:sequence select="map { 'Group' : head($seq1), 'Name' : head($seq2) }"/>
<xsl:sequence select="mf:object-for-each-pair(tail($seq1), tail($seq2))"/>
</xsl:if>
</xsl:function>
<xsl:param name="Variable_01" as="xs:string">88888,777777</xsl:param>
<xsl:param name="Variable_02" as="xs:string">abc,xyz</xsl:param>
<xsl:template match="/" name="xsl:initial-template">
<xsl:sequence select="array { mf:object-for-each-pair(tokenize($Variable_01, ','), tokenize($Variable_02, ',')) }"/>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/6qVRKxk
最后,在没有JSON数组和地图支持的XSLT 2中,您可以使用相同的方法来创建文本输出:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="#all"
version="2.0">
<xsl:output method="text"/>
<xsl:function name="mf:object-for-each-pair" as="xs:string*">
<xsl:param name="seq1"/>
<xsl:param name="seq2"/>
<xsl:if test="exists($seq1) and exists($seq2)">
<xsl:sequence select="concat('{ "Group" : "', $seq1[1], '", "Name" : "', $seq2[1], '" }')"/>
<xsl:sequence select="mf:object-for-each-pair(subsequence($seq1, 2), subsequence($seq2, 2))"/>
</xsl:if>
</xsl:function>
<xsl:param name="Variable_01" as="xs:string">88888,777777</xsl:param>
<xsl:param name="Variable_02" as="xs:string">abc,xyz</xsl:param>
<xsl:template match="/">
<xsl:text>[ </xsl:text>
<xsl:value-of select="mf:object-for-each-pair(tokenize($Variable_01, ','), tokenize($Variable_02, ','))" separator=", "/>
<xsl:text> ]</xsl:text>
</xsl:template>
</xsl:stylesheet>
答案 2 :(得分:0)
这有点粗糙。但这可以完成工作。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:variable name="Variable_01">88888,777777</xsl:variable>
<xsl:variable name="Variable_02">abc,xyz</xsl:variable>
<xsl:template match="/">
<xsl:text>[</xsl:text>
<xsl:call-template name="tokenizeString">
<!-- store anything left in another variable -->
<xsl:with-param name="list" select="$Variable_01"/>
<xsl:with-param name="list2" select="$Variable_02"/>
<xsl:with-param name="delimiter" select="','"/>
</xsl:call-template>
<xsl:text>]</xsl:text>
</xsl:template>
<xsl:template name="tokenizeString">
<!--passed template parameter -->
<xsl:param name="list"/>
<xsl:param name="list2"/>
<xsl:param name="delimiter"/>
<xsl:choose>
<xsl:when test="contains($list, $delimiter)">
<!-- get everything in front of the first delimiter -->
<xsl:text>{"Group":"</xsl:text>
<xsl:value-of select="substring-before($list,$delimiter)"/>
<xsl:text>", "Name":"</xsl:text>
<xsl:call-template name="tokenizeAnother">
<xsl:with-param name="list2" select="$list2"/>
<xsl:with-param name="delimiter" select="$delimiter"/>
</xsl:call-template>
<xsl:text>"},</xsl:text>
<xsl:call-template name="tokenizeString">
<!-- store anything left in another variable -->
<xsl:with-param name="list" select="substring-after($list,$delimiter)"/>
<xsl:with-param name="list2" select="substring-after($list2,$delimiter)"/>
<xsl:with-param name="delimiter" select="$delimiter"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:text>{"Group":"</xsl:text>
<xsl:value-of select="$list"/>
<xsl:text>", "Name":"</xsl:text>
<xsl:call-template name="tokenizeAnother">
<xsl:with-param name="list2" select="$list2"/>
<xsl:with-param name="delimiter" select="$delimiter"/>
</xsl:call-template>
<xsl:text>"}</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="tokenizeAnother">
<xsl:param name="list2"/>
<xsl:param name="delimiter"/>
<xsl:choose>
<xsl:when test="contains($list2, $delimiter)">
<!-- get everything in front of the first delimiter -->
<xsl:value-of select="substring-before($list2,$delimiter)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$list2"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
查看实际情况here。
答案 3 :(得分:0)
为完成此操作,这是一个纯粹的 XSLT 1.0 解决方案,不需要任何扩展功能:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:variable name="Variable_01">88888,777777</xsl:variable>
<xsl:variable name="Variable_02">abc,xyz</xsl:variable>
<xsl:template match="/">
<xsl:text>[</xsl:text>
<xsl:call-template name="tokenize-to-pairs">
<xsl:with-param name="left-text" select="$Variable_01"/>
<xsl:with-param name="right-text" select="$Variable_02"/>
</xsl:call-template>
<xsl:text>]</xsl:text>
</xsl:template>
<xsl:template name="tokenize-to-pairs">
<xsl:param name="left-text"/>
<xsl:param name="right-text"/>
<xsl:param name="delimiter" select="','"/>
<!-- output -->
<xsl:text>{"Group":"</xsl:text>
<xsl:value-of select="substring-before(concat($left-text, $delimiter), $delimiter)" />
<xsl:text>", "Name":"</xsl:text>
<xsl:value-of select="substring-before(concat($right-text, $delimiter), $delimiter)" />
<xsl:text>"}</xsl:text>
<!-- recursive call -->
<xsl:if test="contains($left-text, $delimiter)">
<xsl:text>,</xsl:text>
<xsl:call-template name="tokenize-to-pairs">
<xsl:with-param name="left-text" select="substring-after($left-text, $delimiter)"/>
<xsl:with-param name="right-text" select="substring-after($right-text, $delimiter)"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>