xsl 1.0通过用逗号分隔的项目进行分组 [英] xsl 1.0 Group by with comma separated items
问题描述
我有一个类似于这个的XML
< profiles>
<个人资料>
< customer>客户a< / customer>
<附属品>
<摘要>摘要a< / summary>
<相关>
< solutions> sol1,sol2< / solutions>
< / related>
<附属品>
< / profile>
<个人资料>
< customer> customer b< / customer>
<附属品>
< summary>汇总b< / summary>
<相关>
< solutions> sol1< / solutions>
< / related>
<附属品>
< / profile>
<个人资料>
< customer> customer c< / customer>
<附属品>
< summary>汇总c< / summary>
<相关>
< solutions> sol2,sol3< / solutions>
< / related>
<附属品>
< / profile>
< / profiles>
所需输出
< div id =#sol1>
客户a,摘要a
客户b,摘要b
< / div>
< div id =#sol2>
客户a,摘要a
客户c,摘要c
< / div>
..............
Iam意识到Muenchian分组的方式,但不知道我如何完成,如果我用逗号分隔了group-by元素值。任何帮助将不胜感激。
虽然这在XSLT 2.0中是直接的,但在XSLT中,两遍转换可以产生想要的结果:
< xsl:stylesheet version =1.0
xmlns:xsl =http: //www.w3.org/1999/XSL/Transform
xmlns:ext =http://exslt.org/commonexclude-result-prefixes =ext>
< xsl:output omit-xml-declaration =yesindent =yes/>
< xsl:key name =kSolByValmatch =solutionuse =。/>
< 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>
ext:node-set($ vrtfPass1)
/ * / * / * / *
/ solutions /解决方案
[generate-id()
=
generate-id(key('kSolByVal',。)[1])$ b $ b]
mode =pass2 />
< / xsl:template>
< div id =#{。}>
select =key('kSolByVal',。)/../../../ ../>
< / div>
< / xsl:template>
< xsl:template match =profilemode =pass2>
< xsl:if test =position()= 1>
< xsl:text>&#xA;< / xsl:text>
< / xsl:if>
< xsl:value-of select =
concat(customer,',',* / summary,'& #xA;')/>
< / xsl:template>
< xsl:template match =solutions>
<解决方案>
< / solutions>
< / xsl:template>
< xsl:template match =solutionsname =splitmode =split>
< xsl:param name =pTextselect =。/>
< xsl:if test =string-length($ pText)>
select =concat($ pText,',')/>
substring-before($ vText1,',')/>
<解决方案>
< 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>
<个人资料>
< customer>客户a< / customer>
<附属品>
<摘要>摘要a< / summary>
<相关>
< solutions> sol1,sol2< / solutions>
< / related>
< / collateral>
< / profile>
<个人资料>
< customer> customer b< / customer>
<附属品>
< summary>汇总b< / summary>
<相关>
< solutions> sol1< / solutions>
< / related>
< / collateral>
< / profile>
<个人资料>
< customer> customer c< / customer>
<附属品>
< summary>汇总c< / summary>
<相关>
< solutions> sol2,sol3< / solutions>
< / related>
< / collateral>
< / profile>
< / profiles>
产生了正确的结果:
< div id =#sol1>
客户a,摘要a
客户b,摘要b
< / div>
< div id =#sol2>
客户a,摘要a
客户c,摘要c
< / div>
< div id =#sol3>
客户c,摘要c
< / div>
解释:
-
我们在两次传球中进行转换。 Pass2适用于在提供的XML文档上应用Pass1的结果。
第1遍本质上是任何
解决方案的身份规则覆盖
元素。对 solutions
元素的处理包括对其字符串值进行递归分割。 Pass1的最终结果如下: -
<型材>
<个人资料>
< customer>客户a< / customer>
<附属品>
<摘要>摘要a< / summary>
<相关>
<解决方案>
< solution> sol1< / solution>
< solution> sol2< / solution>
< / solutions>
< / related>
< / collateral>
< / profile>
<个人资料>
< customer> customer b< / customer>
<附属品>
< summary>汇总b< / summary>
<相关>
<解决方案>
< solution> sol1< / solution>
< / solutions>
< / related>
< / collateral>
< / profile>
<个人资料>
< customer> customer c< / customer>
<附属品>
< summary>汇总c< / summary>
<相关>
<解决方案>
< solution> sol2< / solution>
< solution> sol3< / solution>
< / solutions>
< / related>
< / collateral>
< / profile>
< / profiles>
<3> .3。然后,我们对Pass1的结果应用模板(在 mode =pass2
中)。这是一个典型的和传统的Muenchian分组。
I have a XML similar to this
<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>
Desired output
<div id="#sol1">
customer a,summary a
customer b, summary b
</div>
<div id="#sol2">
customer a,summary a
customer c,summary c
</div>
..............
Iam aware of Muenchian way of grouping, but not sure how I can accomplish, if I have comma separated groub-by element values. Any help will be appreciated.
While this is straight-forward in XSLT 2.0, in XSLT a two-pass transformation can produce the wanted results:
<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>
when this transformation is applied on the provided XML document (corrected for well-formedness):
<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>
the wanted, correct result is produced:
<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>
Explanation:
We carry out the transformation in two passes. Pass2 is applied on the result of applying Pass1 on the provided XML document.
Pass 1 is essentially the identity rule overriden for any
solutions
element. The processing of asolutions
element consists in recursive splitting of its string value. The final result of Pass1 is the following:
--
<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>
.3. We then apply templates (in mode="pass2"
) on the result of Pass1. This is a typical and traditional Muenchian grouping.
这篇关于xsl 1.0通过用逗号分隔的项目进行分组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!