总的来说:阅读 Muenchian 分组。
对于这个特定问题(但通常也是有用的建议):将其分解为更小的部分。
一种分解方法:您希望为输入y
中元素的表达式 substring-before(.,'/') 的每个不同值生成一个元素x
。x
或者可能对于该子字符串与其前一个兄弟的相应子字符串不同的每次出现。首先编写一个样式表,它只生成正确数量的y
元素,并具有适当的s
属性值。所以输出是
<y s="Foo"/>
<y s="Bar"/>
你怎么能那样做?
完成后,您需要为y
元素提供内容:对于x
输入中共享相同前缀的每个,打印出字符串值。在最终版本中,您将需要逗号和空格,但正确使用它们涉及一些繁琐的细节,因此编写样式表的下一个版本以生成一系列z
元素作为 的子元素y
:
<y s="Foo"><z>Red</z><z>Green</z><z>Blue</z></y>
<y s="Bar"><z>Hello</z><z>World</z></y>
z
元素需要出现在元素内部y
。因此,生成y
元素的模板更改为:
<xsl:template match="...">
<!--* old code here ... *-->
<xsl:element name="y">
<xsl:attribute name="s">
<xsl:value-of select="..."/>
</xsl:attribute>
<!--* code to produce 'z' elements goes here *-->
</xsl:element>
</xsl:template>
生成z
元素的代码应该是什么样的?在y
给定前缀值的元素中$prefix
,我们希望输入中z
的每个元素都有一个x
共享该前缀的元素。因此,完成这项工作的一种简单方法是仅在该组y
元素上调用应用模板。为了避免干扰匹配x
元素和生成y
元素的模板,给它一个模式。对 apply-templates 的调用可能如下所示:
<xsl:apply-templates mode="z-production"
select="//x[substring-before(.,'/') = $prefix]"/>
现在在 z-production 模式下为 x 元素编写模板。
最后,更改样式表以生成逗号和空格而不是z
元素。
还有其他方法可以将问题分解成更小的部分;有时,从兄弟姐妹到兄弟姐妹而不是从父母到兄弟姐妹会很有帮助。