在this question中,我询问是否可以使用XSLT阻止连续相同值的输出。在这个问题中,我扩展了输入数据,以便XSLT 1.0语法的Muenchian Grouping method更清晰。
是否可以仅使用XSL转换匹配XML文档中第一次出现的值?
我想打印出f2,f3中的每个值,但只打印f1内容的第一个实例,保留顺序。
XML数据
<doc>
<datum>
<f1>One</f1>
<f2>Monday</f2>
<f3>January</f3>
</datum>
<datum>
<f1>One</f1>
<f2>Tuesday</f2>
<f3>February</f3>
</datum>
<datum>
<f1>Two</f1>
<f2>Wednesday</f2>
<f3>March</f3>
</datum>
</doc>
输出
One
-Monday-January
-Tuesday-February
Two
-Wednesday-March
这是Dimitre Novatchev为XSLT 1.0提出的包含字段f1和f2的输入数据集的解决方案。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:key name="kDatumByF1" match="datum" use="f1"/>
<xsl:template match=
"datum[generate-id() = generate-id(key('kDatumByF1', f1)[1])]">
<xsl:value-of select="concat('
', f1)"/>
<xsl:apply-templates select="key('kDatumByF1', f1)/f2" mode="inGroup"/>
</xsl:template>
<xsl:template match="f2" mode="inGroup">
- <xsl:value-of select="."/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
它工作得很好,但我不确定扩展的语法,以在输出中包含字段'f3'。
答案 0 :(得分:2)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:key name="kDatumByF1" match="datum" use="f1"/>
<xsl:template match=
"datum[generate-id() = generate-id(key('kDatumByF1', f1)[1])]">
<xsl:value-of select="concat('
', f1)"/>
<xsl:apply-templates select="key('kDatumByF1', f1)/*[self::f2 | self::f3]" mode="inGroup"/>
</xsl:template>
<xsl:template match="f2" mode="inGroup">
- <xsl:value-of select="."/>
</xsl:template>
<xsl:template match="f3" mode="inGroup">
<xsl:value-of select="concat('-',.)"/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
答案 1 :(得分:1)
此转化:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kDatumByF1" match="datum" use="f1"/>
<xsl:template match=
"datum[generate-id() = generate-id(key('kDatumByF1', f1)[1])]">
<xsl:value-of select="concat(f1, '
')"/>
<xsl:apply-templates mode="inGroup"
select="key('kDatumByF1', f1)/*[self::f2 or self::f3]" />
</xsl:template>
<xsl:template match="f2|f3" mode="inGroup">
<xsl:value-of select="concat('- ',., ' ')"/>
<xsl:if test="not(following-sibling::*[self::f2 or self::f3])">
<xsl:text>
</xsl:text>
</xsl:if>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
应用于提供的XML文档:
<doc>
<datum>
<f1>One</f1>
<f2>Monday</f2>
<f3>January</f3>
</datum>
<datum>
<f1>One</f1>
<f2>Tuesday</f2>
<f3>February</f3>
</datum>
<datum>
<f1>Two</f1>
<f2>Wednesday</f2>
<f3>March</f3>
</datum>
</doc>
生成想要的正确结果:
One
- Monday - January
- Tuesday - February
Two
- Wednesday - March
<强>解释强>:
正确使用 Muenchian grouping method 。
请注意:
即使f2
和f3
可以按任何顺序排列,此解决方案也会生成所需结果。