我正在尝试通过以下示例使用xsl:key分组创建多个“产品”
<xsl:key name="product-by-pkg" match="GoodsItem" use="PackageTypeCode"
<xsl:for-each select="GoodsItem[count(. | key('product-by-pkg', PackageTypeCode)[1]) = 1]">
<product type="{PackageTypeCode}">
<quantity>
<!-- count current group -->
<xsl:value-of select="count(key('product-by-pkg', PackageTypeCode))" />
</quantity>
</product>
</xsl:for-each>
在此来源上
<GoodsItem>
<PackageTypeCode>PC</PackageTypeCode>
</GoodsItem>
<GoodsItem>
<PackageTypeCode>PE</PackageTypeCode>
</GoodsItem>
<GoodsItem>
<PackageTypeCode>PC</PackageTypeCode>
</GoodsItem>
<GoodsItem>
<PackageTypeCode>XX</PackageTypeCode>
</GoodsItem>
<GoodsItem>
<PackageTypeCode>OA</PackageTypeCode>
<GoodsItem>
<PackageTypeCode>OF</PackageTypeCode>
</GoodsItem>
<GoodsItem>
<PackageTypeCode>CW</PackageTypeCode>
</GoodsItem>
我想做的就是使用上述转换创建一个产品标签,并且PackageTypeCodes不是YY或XX,或者使用代码与我的参数不匹配的模式。 我基本上是在寻找一种适用于PackageTypeCode!= XX的东西。 所以我想遍历所有PackageTypeCodes,在其中我设置要为其创建产品的代码的参数。 然后是第二个,我将第一个参数中的“未使用”组合到具有@type PC的产品上
所以我的结果看起来像
<extraGoodsData>
<product type="PE">
<quantity>1</quantity>
</product>
<product type="OA">
<quantity>1</quantity>
</product>
<product type="OF">
<quantity>1</quantity>
</product>
<product type="CW">
<quantity>1</quantity>
</product>
</extraGoodsData>
并且我希望将XX作为默认值计入PC,因此在第二次迭代中将使用与我的参数不匹配的第二次迭代来创建
<product type="PC">
<!--quantity should be equal to the number of PC + non matching PackageTypeCodes in the first iteration-->
<quantity>3</quantity>
</product>
最终结果是这样的
<extraGoodsData>
<product type="PE">
<quantity>1</quantity>
</product>
<product type="OA">
<quantity>1</quantity>
</product>
<product type="OF">
<quantity>1</quantity>
</product>
<product type="CW">
<quantity>1</quantity>
</product>
<!--number of PC PackageTypeCodes + non matching in the first count-->
<product type="PC">
<quantity>3</quantity>
</product>
</extraGoodsData>
在XSLT1.0中可以吗?
编辑-------
与我想要的东西不匹配的所有packageTypeCodes,例如,应该对等于PE,OA,CW,OF的所有东西以及我想要添加的所有东西执行针对每个的packageTypeCodes。那些未包含的PC,XX,YY,ZZ等应全部组合在PC下,且数量等于PC + XX + YY + ZZ的数量但在1个产品标签下。
<!--for PE OA OF CW-->
<xsl:for-each select="GoodsItem[count(. | key('product-by-pkg', PackageTypeCode)[1]) = 1]">
<product type="{PackageTypeCode}">
<quantity>
<!-- count current group -->
<xsl:value-of select="count(key('product-by-pkg', PackageTypeCode))" />
</quantity>
</product>
</xsl:for-each>
<!--for PC,XX,ZZ,YY etc-->
<xsl:for-each select="GoodsItem[count(. | key('product-by-pkg', PackageTypeCode)[1]) = 1]">
<product type="PC">
<quantity>
<xsl:value-of select="count(key('product-by-pkg', PackageTypeCode))" />
</quantity>
</product>
</xsl:for-each>
答案 0 :(得分:1)
我建议您通过两次传递来简化问题:首先,将要分组在一起的所有代码重命名为PC
。然后将Muenchian分组应用于结果:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="pkg" match="package" use="."/>
<xsl:template match="/root">
<xsl:variable name="packages">
<xsl:for-each select="GoodsItem">
<package>
<xsl:choose>
<xsl:when test="PackageTypeCode='PE' or PackageTypeCode='OA' or PackageTypeCode='OF' or PackageTypeCode='CW'">
<xsl:value-of select="PackageTypeCode"/>
</xsl:when>
<xsl:otherwise>PC</xsl:otherwise>
</xsl:choose>
</package>
</xsl:for-each>
</xsl:variable>
<output>
<xsl:for-each select="exsl:node-set($packages)/package[count(. | key('pkg', .)[1]) = 1]">
<product type="{.}">
<quantity>
<!-- count current group -->
<xsl:value-of select="count(key('pkg', .))" />
</quantity>
</product>
</xsl:for-each>
</output>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:msxml="urn:schemas-microsoft-com:xslt"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="product-by-pkg" match="GoodsItem" use="PackageTypeCode"/>
<!-- I modified the code to handle dynamic exceptions. You
need to created the exceptionList in this format from what ever source you have. -->
<xsl:variable name="exceptions">
<xsl:element name="PackageTypeCode">XX</xsl:element>
<xsl:element name="PackageTypeCode">YY</xsl:element>
</xsl:variable>
<!-- Use whatever namespace you have set up. I am using msxml. -->
<xsl:variable name="exceptionList" select="msxml:node-set($exceptions)"/>
<!-- I added root to you xml. Use whatever parent node you have. -->
<xsl:template match="root">
<xsl:copy>
<xsl:for-each select="GoodsItem[generate-id(.) = generate-id(key('product-by-pkg', PackageTypeCode)[not(PackageTypeCode = $exceptionList/PackageTypeCode)][1])]">
<xsl:element name="product">
<xsl:attribute name="type">
<xsl:value-of select="PackageTypeCode"/>
</xsl:attribute>
<xsl:element name="quantity">
<xsl:choose>
<xsl:when test="PackageTypeCode = 'PC'">
<xsl:value-of select="count(key('product-by-pkg', PackageTypeCode)) + count(key('product-by-pkg', $exceptionList/PackageTypeCode))" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="count(key('product-by-pkg', PackageTypeCode))" />
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>