我是XSL的新手,正在努力弄清楚如何做我需要做的事情。我有一个订单数据集,并将其转换为我可以用来将订单导入到履行系统的格式。我正在使用for-each迭代节点并输出数据。足够简单到这一点。
现在新的要求是我需要检查项目子节点中的值。如果定义了任何这些值,我需要在输出中添加一行。棘手的部分是这个额外的行是在项目级别决定的,但是即使在多个子节点中找到该值,也只应该在我的输出中。这就是我无法分配变量值或破坏for-each的地方。我确定某种类型的递归是答案,但我无法弄清楚如果不重复我试图找到的每个属性的所有项目节点,它将如何工作。我也受限于XSLT 1.0,因为这必须通过不支持2.0的第三方应用程序来完成。
以下是我的数据集
的示例<orders>
<order>
<id>1</id>
<items>
<item>
<sku>12345</sku>
<price>5.00</sku>
</item>
<item>
<sku>23456</sku>
<price>4.00</sku>
<options>
<option1>item_upgrade</option1>
</option>
</item>
<item>
<item>
<sku>34567</sku>
<price>3.00</sku>
<options>
<option2>finish_upgrade</option2>
</option>
</item>
<item>
<sku>45678</sku>
<price>2.00</sku>
<options>
<option1>item_upgrade</option1>
<option2>finish_upgrade</option2>
</option>
</item>
</items>
</order>
<order>
<id>2</id>
<items>
<item>
<sku>12345</sku>
<price>5.00</sku>
</item>
<item>
<sku>23456</sku>
<price>4.00</sku>
</item>
<item>
<item>
<sku>34567</sku>
<price>3.00</sku>
</item>
</items>
</order>
<order>
....
</order>
</orders>
最终我希望看到的是
1 12345 5.00
1 23456 4.00
1 99999 0.00
1 34567 3.00
1 88888 0.00
1 45678 2.00
2 12345 5.00
2 23456 4.00
2 34567 3.00
...
99999和88888在源数据中不存在,但在履行系统中是静态值,分别代表item_upgrade和finish_upgrade。如果在订单中的任何项目上定义了item_upgrade,则应将99999行添加到输出中。对于finish_upgrade也是如此,这需要为输出添加88888行。这些静态条目(例如99999)的排序顺序无关紧要,只要它仍按顺序/ id排序即可。多个项目节点上可以存在相同的选项,并且不一定存在于任何项目节点上。
我正在使用它是为我正在创建的导入文件中的订单添加附加费。这些费用在订单级别,如果在订单中包含的任何项目上选择了特定选项,则应为单行。费用在源数据中不存在,无法添加。幸运的是,它们是静态值,因此我只需要确定何时添加它们。
目前采用for-each而不考虑这些费用的做法看起来像是
<xsl:template match="/">
<xsl:for-each select="orders/order/items/item">
<xsl:value-of select="../../id" />
<xsl:text> </xsl:text>
<xsl:value-of select="sku" />
<xsl:text> </xsl:text>
<xsl:value-of select="price" />
</xsl:for-each>
</xsl:template>
如果我想为任何出现添加静态费用,在一个订单中多次允许,我会添加类似
的内容<xsl:template match="/">
<xsl:for-each select="orders/order/items/item">
<xsl:value-of select="../../id" />
<xsl:text> </xsl:text>
<xsl:value-of select="sku" />
<xsl:text> </xsl:text>
<xsl:value-of select="price" />
<xsl:if test="options/option1='item_upgrade'">
<xsl:value-of select="../../id" />
<xsl:text> 99999 0.00</xsl:text>
</xsl:if>
<xsl:if test="options/option2='finish_upgrade'">
<xsl:value-of select="../../id" />
<xsl:text> 88888 0.00</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
这就是我被困住的地方。每个订单需要添加一次此值,但是是否需要添加它需要在项目级别决定。我希望这对于能够更好地理解这一点的人来说很容易,但是到目前为止,我已经采取了任何方法,我会回过头来为每次出现添加额外的静态线,而不是为了整个订单添加一次,即使是相同的选项是在单个订单中的多个项目上定义的。任何人都可以引导我采用一种适用于此的方法吗?提前谢谢
答案 0 :(得分:0)
基本上,这是分组问题,因为您使用的是XSLT 1.0,所以最好使用Muenchian method进行处理。
考虑以下样式表:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8" />
<xsl:key name="opt" match="options/*" use="concat(ancestor::order/id, '|', .)" />
<xsl:template match="/orders">
<xsl:for-each select="order">
<xsl:variable name="order-id" select="id" />
<!-- items -->
<xsl:for-each select="items/item">
<xsl:value-of select="$order-id" />
<xsl:text>	</xsl:text>
<xsl:value-of select="sku" />
<xsl:text>	</xsl:text>
<xsl:value-of select="price" />
<xsl:text> </xsl:text>
</xsl:for-each>
<!-- options -->
<xsl:for-each select="items/item/options/*[count(. | key('opt', concat($order-id, '|', .))[1]) = 1]">
<xsl:value-of select="$order-id" />
<xsl:text>	</xsl:text>
<xsl:value-of select="." />
<xsl:text>	0.00 </xsl:text>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
当应用于以下格式良好的(!)输入示例时:
<强> XML 强>
<orders>
<order>
<id>1</id>
<items>
<item>
<sku>12345</sku>
<price>5.00</price>
</item>
<item>
<sku>23456</sku>
<price>4.00</price>
<options>
<option1>red</option1>
</options>
</item>
<item>
<sku>34567</sku>
<price>3.00</price>
<options>
<option2>circle</option2>
</options>
</item>
<item>
<sku>45678</sku>
<price>4.00</price>
<options>
<option1>red</option1>
</options>
</item>
</items>
</order>
<order>
<id>2</id>
<items>
<item>
<sku>12345</sku>
<price>5.00</price>
</item>
<item>
<sku>23456</sku>
<price>4.00</price>
</item>
<item>
<sku>34567</sku>
<price>3.00</price>
</item>
</items>
</order>
</orders>
结果将是:
1 12345 5.00
1 23456 4.00
1 34567 3.00
1 45678 4.00
1 red 0.00
1 circle 0.00
2 12345 5.00
2 23456 4.00
2 34567 3.00