我有一个与此类似的XML
<profiles>
<profile>
<customer>customer a </customer>
<collateral>
<summary>summary a</summary>
<related>
<solutions>sol1,sol2</solutions>
</related>
<collateral>
</profile>
<profile>
<customer>customer b </customer>
<collateral>
<summary>summary b</summary>
<related>
<solutions>sol1</solutions>
</related>
<collateral>
</profile>
<profile>
<customer>customer c </customer>
<collateral>
<summary>summary c</summary>
<related>
<solutions>sol2,sol3</solutions>
</related>
<collateral>
</profile>
</profiles>
期望的输出
<div id="#sol1">
customer a,summary a
customer b, summary b
</div>
<div id="#sol2">
customer a,summary a
customer c,summary c
</div>
..............
我知道Muenchian的分组方式,但不知道我怎么能完成,如果我用逗号分隔的groub-by元素值。任何帮助将不胜感激。
答案 0 :(得分:1)
虽然这在XSLT 2.0中很简单,但在XSLT中,两遍转换可以产生想要的结果:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common" exclude-result-prefixes="ext">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kSolByVal" match="solution" use="."/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:variable name="vrtfPass1">
<xsl:apply-templates/>
</xsl:variable>
<xsl:apply-templates select=
"ext:node-set($vrtfPass1)
/*/*/*/*
/solutions/solution
[generate-id()
=
generate-id(key('kSolByVal', .)[1])
]"
mode="pass2"/>
</xsl:template>
<xsl:template mode="pass2" match="solution">
<div id="#{.}">
<xsl:apply-templates mode="pass2"
select="key('kSolByVal', .)/../../../.."/>
</div>
</xsl:template>
<xsl:template match="profile" mode="pass2">
<xsl:if test="position() = 1">
<xsl:text>
</xsl:text>
</xsl:if>
<xsl:value-of select=
"concat(customer, ', ', */summary, '
')"/>
</xsl:template>
<xsl:template match="solutions">
<solutions>
<xsl:apply-templates select="." mode="split"/>
</solutions>
</xsl:template>
<xsl:template match="solutions" name="split" mode="split">
<xsl:param name="pText" select="."/>
<xsl:if test="string-length($pText)">
<xsl:variable name="vText1"
select="concat($pText, ',')"/>
<xsl:variable name="vPart" select=
"substring-before($vText1, ',')"/>
<solution>
<xsl:value-of select="$vPart"/>
</solution>
<xsl:call-template name="split">
<xsl:with-param name="pText"
select="substring($pText, string-length($vPart)+2)"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
将此转换应用于提供的XML文档(已针对格式良好进行了更正):
<profiles>
<profile>
<customer>customer a </customer>
<collateral>
<summary>summary a</summary>
<related>
<solutions>sol1,sol2</solutions>
</related>
</collateral>
</profile>
<profile>
<customer>customer b </customer>
<collateral>
<summary>summary b</summary>
<related>
<solutions>sol1</solutions>
</related>
</collateral>
</profile>
<profile>
<customer>customer c </customer>
<collateral>
<summary>summary c</summary>
<related>
<solutions>sol2,sol3</solutions>
</related>
</collateral>
</profile>
</profiles>
产生了想要的正确结果:
<div id="#sol1">
customer a , summary a
customer b , summary b
</div>
<div id="#sol2">
customer a , summary a
customer c , summary c
</div>
<div id="#sol3">
customer c , summary c
</div>
<强>解释强>:
我们分两次进行转换。 Pass2应用于在提供的XML文档上应用Pass1的结果。
Pass 1实际上是任何solutions
元素的身份规则覆盖。 solutions
元素的处理包括递归拆分其字符串值。 Pass1的最终结果如下:
-
<profiles>
<profile>
<customer>customer a </customer>
<collateral>
<summary>summary a</summary>
<related>
<solutions>
<solution>sol1</solution>
<solution>sol2</solution>
</solutions>
</related>
</collateral>
</profile>
<profile>
<customer>customer b </customer>
<collateral>
<summary>summary b</summary>
<related>
<solutions>
<solution>sol1</solution>
</solutions>
</related>
</collateral>
</profile>
<profile>
<customer>customer c </customer>
<collateral>
<summary>summary c</summary>
<related>
<solutions>
<solution>sol2</solution>
<solution>sol3</solution>
</solutions>
</related>
</collateral>
</profile>
</profiles>
0.3。然后,我们在Pass1的结果上应用模板(在mode="pass2"
中)。这是典型的传统Muenchian分组。