使用XSLT 1.0和Muenchian分组方法如果单个字段的值不变,如何防止连续输出单个字段

时间:2012-08-15 02:33:52

标签: xml xslt

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('&#xA;', 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'。

2 个答案:

答案 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('&#xA;', 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, '&#xA;')"/>
       <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>&#xA;</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

请注意

即使f2f3可以按任何顺序排列,此解决方案也会生成所需结果。