XSLT分组麻烦

时间:2017-02-16 18:00:56

标签: xslt grouping

我正在努力从迭代编程跳转到XSLT。我之前问了一个问题,这有点帮助,但现在我又回来了。

我正在尝试为使用XSLT 1.0的系统生成订单导入文件。我需要做一些逻辑,为了简化它,我想出了下面的示例源数据

<orders>
  <order>
     <id>1</id>
     <items>
       <item>
          <sku>12345</sku>
          <addon></addon>
       </item>
       <item>
          <sku>23456</sku>
          <addon>A</addon>
       </item>
       <item>
          <sku>34567</sku>
          <addon>B</addon>
       </item>
     </items>
  </order>
  <order>
     <id>2</id>
     <items>
       <item>
          <sku>12345</sku>
          <addon></addon>
       </item>
       <item>
          <sku>23456</sku>
          <addon></addon>
       </item>
     </items>
  </order>
</orders>

然后对于输出我只想查看订单ID和“是”或“否”,具体取决于该订单中包含的任何项目是否具有为插件定义的值。我不关心那个值是什么,但是如果它对于任何项目都是空白的,我希望输出为是,如果所有项目对于addon都是空白的那么输出应该对该顺序显示no。对于上面的示例数据,输出应该只是

1 Yes
2 No

首先猜测某事是

<xsl:key name="opt" match="item/addon" use="concat(ancestor::orders/order/id, '|', .)" />

<xsl:template match="/">
   <xsl:for-each select="orders/order">
      <xsl:value-of select="id" />
      <xsl:for-each select="orders/order/item/addon[count(. | key('opt', concat(orders/order/id), '|', .))[1]) = 1]">
         <xsl:choose>
            <xsl:when test=".=''"><xsl:text>Yes</xsl:text></xsl:when>          
            <xsl:otherwise><xsl:text>No</xsl:text></xsl:otherwise>
         </xsl:choose>
      </xsl:for-each>
    </xsl:for-each>   
</xsl:template>

我承认我并不完全理解密钥中的语法,而且它比我自己想出的任何内容都更复制/粘贴。看看我上面的尝试,我认为这会输出Yes两次,因为addon对于#1的项目有不同的值。

如果我用我理解的编程语言这样做,我会使用像这样的伪代码

bool hasAddon = false;
foreach(item in items)
{
    if(item.addon != "")
    {
       hasAddon = true;
       break;
    }
}
if(hasAddon)
   output Yes
else
   output No

这就是我努力将伪代码翻译成XSLT中可用的东西的地方,因为我知道 - 在XSLT中每个都不一样,你不能打破for-each,你只能设置变量的价值一次。如果没有这些选项,我会感到迷失,并且在理解密钥和递归模板方面遇到问题,足以找到我自己的解决方案。任何帮助都很棒

1 个答案:

答案 0 :(得分:3)

我不明白你需要什么钥匙,你只需检查<xsl:choose><xsl:when test="items/item/addon[normalize-space()]">Yes</xsl:when><xsl:otherwise>No</xsl:otherwise></xsl:choose>即可。在<xsl:for-each select="orders/order">内。