我正在努力从迭代编程跳转到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,你只能设置变量的价值一次。如果没有这些选项,我会感到迷失,并且在理解密钥和递归模板方面遇到问题,足以找到我自己的解决方案。任何帮助都很棒
答案 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">
内。