【问题标题】:Grouping is not working in XSLT 1.0分组在 XSLT 1.0 中不起作用
【发布时间】:2013-07-05 16:01:38
【问题描述】:

我有一个如下所示的 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>

在 .问题是在第二个元素的匹配过程中,没有被打印出来。我一定是犯了一些愚蠢的错误。

我哪里做错了?

【问题讨论】:

    标签: xslt-1.0 xslt-grouping


    【解决方案1】:

    这里有三个问题:

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

    当我们使用“catA”元素验证这一点时,您可以轻松理解问题;
    通过输出所有索引的 'catA' 元素,我们得到以下节点列表:
    &lt;xsl:copy-of select="key('groupElement', 'catA')"/&gt;
    ->
    <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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-28
      • 2010-12-26
      • 1970-01-01
      • 2021-05-09
      • 2021-11-20
      • 2013-03-17
      • 2015-01-02
      相关资源
      最近更新 更多