嵌套for-each-group Calls中的增量器

时间:2013-10-08 00:03:02

标签: xslt xslt-2.0

在看了社区的大量精彩建议后,先在这里发帖。

我在XSLT 2.0中有三个字段,都在同一级别(肩膀,膝盖和脚趾)。我需要根据肩膀和膝盖的独特组合输出脚趾的总和,所以我创建了两个嵌套的for-each-groups。在每个输出上,我还需要输出从1到肩膀和膝盖的独特组合的增量器。

这个增量器是我遇到问题的地方。我最接近的是调用position(),但是如果我在最里面的组中调用它,则计数器会在每个独特的肩膀上重置。如果我在最外面的组中调用它,那么独特肩膀内的每个膝盖都会获得相同的值,然后它会在每个独特的肩膀上重置。如果我完全在组外调用它,它永远不会超过1.我也尝试使用xsl:number,keys等无济于事。在这些情况下,仍然会打印正确的行数,但增量值会查看单个非分组值。

我在模板之间读到了一个关于“隧道”值的建议,但是我无法让它工作,主要是因为我认为我没有正确调用模板(这些字段是同一级别的而不是亲子)。是否有关于为每个小组或其他方式进行此项工作的想法?非常感谢提前。

示例XML:

<bodies>
<parts>
    <shoulders>shoulders1</shoulders>
    <knees>knees1</knees>
    <toes>1</toes>
</parts>
<parts>
    <shoulders>shoulders2</shoulders>
    <knees>knees2</knees>
    <toes>2</toes>
</parts>
<parts>
    <shoulders>shoulders1</shoulders>
    <knees>knees2</knees>
    <toes>10</toes>
</parts>
<parts>
    <shoulders>shoulders2</shoulders>
    <knees>knees1</knees>
    <toes>10</toes>
</parts>
<parts>
    <shoulders>shoulders1</shoulders>
    <knees>knees1</knees>
    <toes>9</toes>
</parts>
<parts>
    <shoulders>shoulders2</shoulders>
    <knees>knees2</knees>
    <toes>8</toes>
</parts>
</bodies>

示例XSLT:

<xsl:stylesheet exclude-result-prefixes="xsl" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:this="urn:this-stylesheet" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <xsl:template match="/">
      <xsl:for-each-group select="bodies/parts" group-by="shoulders">
         <xsl:for-each-group select="current-group()" group-by="knees">
            <xsl:value-of select="shoulders"/>
            <xsl:text>, </xsl:text>
            <xsl:value-of select="knees"/>
            <xsl:text>, </xsl:text>
            <xsl:value-of select="sum(current-group()/toes)"/>
            <xsl:text>, </xsl:text>
            <xsl:value-of select="position()"/>
            <xsl:text>. </xsl:text> 
         </xsl:for-each-group>
      </xsl:for-each-group>
   </xsl:template>
</xsl:stylesheet>

结果输出:

肩膀1,膝盖1,10,1肩膀1,膝盖2,10,2肩膀2,膝盖2,10,1肩膀2,膝盖1,10,2。

期望的输出:

肩膀1,膝盖1,10,1肩膀1,膝盖2,10,2肩膀2,膝盖2,10,3肩膀2,膝盖1,10,4。

2 个答案:

答案 0 :(得分:1)

如果你有两个这样的嵌套xsl:for-each-group指令,那么另一种方法是对复合键进行单级分组,如下所示:

<xsl:for-each-group select="bodies/parts" group-by="concat(shoulders, '~', knees)">

如果我已正确理解要求,position()将会增加您的查找方式。

当然,如果您真的想要生成外部组很重要的分层结构输出,那么这不起作用。

答案 1 :(得分:0)

我现在已经尝试了三次,我认为你必须处理你的结果,然后计算它们。我已经没时间试图找到一种内联计数的方法,因为我认为它无法完成。

<xsl:stylesheet exclude-result-prefixes="xsl" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:this="urn:this-stylesheet" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <xsl:template match="/">
     <xsl:variable name="results" as="xsd:string*">
      <xsl:for-each-group select="bodies/parts" group-by="shoulders">
         <xsl:for-each-group select="current-group()" group-by="knees">
           <xsl:value-of>
            <xsl:value-of select="shoulders"/>
            <xsl:text>, </xsl:text>
            <xsl:value-of select="knees"/>
            <xsl:text>, </xsl:text>
            <xsl:value-of select="sum(current-group()/toes)"/>
            <xsl:text>,</xsl:text>
           </xsl:value-of>
         </xsl:for-each-group>
      </xsl:for-each-group>
     </xsl:variable>
     <xsl:for-each select="$results">
        <xsl:value-of select=".,position()"/>
        <xsl:text>. </xsl:text>
     </xsl:for-each>
   </xsl:template>
</xsl:stylesheet>