【问题标题】:How to combine group-starting-with and group-by in XSLT 2.0?如何在 XSLT 2.0 中结合 group-starting-with 和 group-by?
【发布时间】:2012-07-17 17:48:55
【问题描述】:

我需要在 XSLT 2.0 中结合 group-starting-with 和 group-by

<xsl:for-each-group select="xxx[@attr='yyy']" group-by="@id" group-starting-with="xxx[@attr='yyy']">
...
</xsl:for-each-group>

如何实现这样的组合?

输入:

<root> 
        <library id="L1">
            <genre id="a">
                <shelf1 id="1">                
                    <book id="a1" action="borrow">
                        <attributes>
                            <user>John</user>                    
                        </attributes>
                        <other1>y</other1>
                    </book>  
                    <book id="a1" action="extend">
                        <attributes>
                            <user>Woo</user>           
                            <length>3</length>
                        </attributes>
                        <other2>y</other2>
                    </book> 
    </shelf1>
</genre>
    </library>
    </root>

输出:

<root> 
    <library id="L1">
        <genre id="a">
            <shelf1 id="1">                
                <book id="a1" action="borrow">
                    <attributes>
                        <user>Woo</user>           
                        <length>3</length>                   
                    </attributes>
                    <other1>y</other1>
                </book> 
</shelf1>
</genre>
</library>
</root>

我的 XSL sn-p:

<xsl:template match="genre/*">
        <xsl:copy>
            <xsl:apply-templates select="@*" />

            <xsl:apply-templates select="
     book[@action='extend']                             
         [not( preceding-sibling::book[@action='borrow'])]" />


              <xsl:for-each-group
                select="book[@action='borrow'] 
             |   
            book[@action='extend']
                [preceding-sibling::book[@action='borrow']]"
                group-by="@id" group-starting-with="book[@action='borrow']"> (: "This is the one which needs to be combined :)
                    <xsl:for-each select="current-group()[1]">
                        <xsl:copy>   
                            <xsl:apply-templates select="@*" />
                            <xsl:call-template name="merge-books-deeply">    
                                <xsl:with-param name="books" select="current-group()" />
                                <xsl:with-param name="name-path" select="()" />
                            </xsl:call-template>
                        </xsl:copy>
                    </xsl:for-each>     
                </xsl:for-each-group>


            <xsl:apply-templates select="                             
     node()[ not( self::book[@action=('borrow','extend')])]" />

        </xsl:copy>
    </xsl:template>

对于每个具有相同@idaction=borrow 的节点,后跟一个或多个 节点和action=extend

  • 将其合并到具有 action=borrow 的节点。
  • 将子属性合并在一起,使其具有兄弟姐妹中具有最新值的所有唯一属性。
  • 保持其他孩子不变

谢谢。 约翰

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    语言中提供的结构是 group-by 或 group-starting-with,因此当您要求将它们组合起来时,我们不清楚您期望什么。

    你可以做的是嵌套for-each-group 例如

    <xsl:for-each-group select="xxx[@att = 'yyy']" group-by="@id">
      <xsl:for-each-group select="current-group()" group-starting-with="xxx[@attr = 'yyy']">...</xsl:for-each-group>
    </xsl:for-each-group>
    

    虽然在写这篇文章时,我想知道有一个分组人口 xxx[@att = 'yyy'] 和一个以模式 xxx[@att = 'yyy'] 开头的组有什么意义。

    所以我认为您需要更详细地解释您的输入的外观以及您希望如何对其进行分组。

    【讨论】:

    • 我已将 xsl sn-p 添加到输入和预期输出中。你介意看看吗?非常感谢。
    【解决方案2】:

    我想应该这样做:

    <xsl:template match="root">
        <xsl:apply-templates select="library | genre"/>
        <xsl:apply-templates select="shelf1"/>
    </xsl:template>
    
    <xsl:template match="library | genre">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
    
            <xsl:apply-templates select="library | genre | shelf1"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="shelf1">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
    
            <xsl:for-each-group select="current()/book" group-by="@id">
                <book id="{current-grouping-key()}" action="borrow">
                    <xsl:copy-of select="current-group()[@action='extend']/*"/>
                </book>
            </xsl:for-each-group>
    
        </xsl:copy>
    </xsl:template>
    

    【讨论】:

      猜你喜欢
      • 2015-08-26
      • 2015-03-17
      • 1970-01-01
      • 2017-07-02
      • 2012-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-30
      相关资源
      最近更新 更多