分组在XSLT1.0中不起作用



我有一个类似于下面的XML。

<minimums type="table">       
      <minLine>
        <minId>S-4LS16L</minId>
        <catA>5550</catA>
        <catA>1800</catA>      
        <catB>5550</catB>
        <catB>1800</catB>     
        <catC>5550</catC>
        <catC>1800</catC>      
      </minLine>    
      <minLine>
        <minId>S-LOC16L</minId>
        <catA>5660</catA>
        <catA>2400</catA>        
        <catB>5660</catB>
        <catB>2400</catB>           
        <catC>2400</catC>
        <catC>310</catC>      
      </minLine>   
 </minimums>

现在我想使用XSL对catA、catB、catC等重复元素进行分组。

下面是我的XSLT部分。

 <xsl:key name ="groupElement" match ="*" use="name(.)"/>
  <xsl:template match ="/">
    <xsl:apply-templates/>
  </xsl:template>
  <xsl:template match="minLine">  
    <xsl:for-each select="*[generate-id()= generate-id(key('groupElement', name(.)))]">
      <xsl:comment> This is Not get Printed during second match of minLine element</xsl:comment>
    </xsl:for-each>
  </xsl:template>

在的第一场比赛中表现良好。问题是在第二个元素的匹配过程中,没有被打印出来。我一定是犯了一个愚蠢的错误。

我哪里做错了?

这里有三个问题:

  1. 您的密钥包含所有元素
  2. generate-id()只获取节点集的第一个节点(按文档顺序)
  3. 使用generate-id()或count()进行简单的"muenchian"分组,其中只获取查找到的节点中的第一个节点,不适用于嵌套结构

当我们用"catA"元素验证这一点时,您可以很容易地理解问题
通过输出所有索引的"catA"元素,我们得到以下节点列表:
<xsl:copy-of select="key('groupElement', 'catA')"/>
->
<catA>5550</catA>
<catA>1800</catA>
<catA>5660</catA>
<catA>2400</catA>

现在,因为generate-id()总是取第一个节点,所以很明显,在第二个"minLine"元素的匹配过程中不会发生任何事情。

解决方案

你可以通过以下方式实现你想要的:

  1. 仅为顺序出现的"minLine/*"子级中的第一个进行索引
  2. 仅选择索引的"minLine/*"子级
<!-- index first of sequentially occurring minLine children -->
<xsl:key name ="minLine_key" match="minLine/*[name() != name(preceding-sibling::*[1])]" use="name()"/>
<xsl:template match ="/">
    <xml>
        <xsl:apply-templates/>
    </xml>
</xsl:template>
<xsl:template match="minLine">
    <!-- select indexed children: look up nodes by name and test wether current is included in the node-set -->
    <xsl:for-each select="*[count(. | key('minLine_key', name())) = count(key('minLine_key', name()))]">
        <xsl:copy-of select="."/>
    </xsl:for-each>
</xsl:template>

相关内容

  • 没有找到相关文章

最新更新