2017-02-16 158 views
1

我正在努力从迭代编程跳转到XSLT。我之前在这里提出了一个问题,并且帮助了很多,但现在我又回到了另一个问题。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和“是”或“否”,这取决于关于包含在该顺序中的任何项目是否具有为插件定义的值。我不在乎这个值是什么,但是如果除了空白之外的任何项目,我希望输出为yes,并且如果所有项目对于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> 

我承认我不完全了解关键中的语法和它更副本/粘贴比我能想出的任何东西。看看我上面的尝试,但我会认为这将输出是两次,因为插件将在顺序#1项上具有不同的值。

如果我是在一种编程语言,我知道这样做,我会用这样的伪

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

这就是我挣扎,因为我知道伪代码转换成可用的XSLT东西for-each在XSLT中并不完全相同,所以不能为每个对象分配一次,并且只能设置一次变量的值。如果没有这些选项,我会感到迷茫,并且在理解关键字和递归模板时遇到问题,足以潜在地找到解决方案。任何帮助将是真棒

+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">

+0

我认为我需要将我的项目和该插件进行分组,因此我没有根据可以在该字段中的各种值进行多次报告。就像我说的,这里是业余爱好者。你能解释一下item/addon [normalize-space()]是指什么吗?不要质疑它,但我想了解它在做什么。如果这就是为了在给定字段中对值进行通用检查而需要做的,那么是的,这应该很好。 – rsly

+1

@DanielHaley,感谢您的纠正,我编辑了代码片段。 –

+1

在''内,'order'元素是上下文节点,然后是'>(与Daniel Haley指出的更正一起)检查是否有一个带有除了空格以外的文本内容的addon后裔,因此它用一个单一的表达式来检查你想要在命令式方法中使用循环做什么。使用XPath时,如果在布尔上下文中使用类似于'xsl:if/when test'的表达式,则在路径选择至少一个节点时计算结果为真,如果所选节点集为空则计算结果为 –