我使用XSLT : Cummulative Sum (Conditional)的答案作为“基础”来对不同的xml进行求和,而我得不到正确的总和。
应仅为Root / Items / Result / Sku中的'skus'创建输出。对于Root / Providers / Result /
中唯一的提供者,累计和应按“提供者质量”(主要,损坏)分组我确信总和中的谓词条件是错误的。但我无法弄清楚这个问题。我将不胜感激任何帮助。谢谢!
示例XML:
<?xml version="1.0" encoding="UTF-8"?>
<Root>
<Items>
<Result>
<Sku>XYZ</Sku>
</Result>
<Result>
<Sku>ABC</Sku>
</Result>
</Items>
<Providers>
<Result>
<ProviderCode>1_M</ProviderCode>
<Quality>Main</Quality>
</Result>
<Result>
<ProviderCode>1_D</ProviderCode>
<Quality>Damaged</Quality>
</Result>
<Result>
<ProviderCode>2_M</ProviderCode>
<Quality>Main</Quality>
</Result>
<Result>
<ProviderCode>2_D</ProviderCode>
<Quality>Damaged</Quality>
</Result>
</Providers>
<Message>
<Body>
<Inventory>
<SKU>
<SKU>AXYZ</SKU>
<Description>XYZ Description</Description>
<Providers>
<Provider>
<ProviderCode>1_M</ProviderCode>
<Qty>100</Qty>
</Provider>
<Provider>
<ProviderCode>2_M</ProviderCode>
<Qty>67</Qty>
</Provider>
<Provider>
<ProviderCode>2_D</ProviderCode>
<Qty>75</Qty>
</Provider>
<Provider>
<ProviderCode>3_M</ProviderCode>
<Qty>74</Qty>
</Provider>
<Provider>
<ProviderCode>4</ProviderCode>
<Qty>62</Qty>
</Provider>
</Providers>
</SKU>
<SKU>
<SKU>ABC</SKU>
<Description>ABC Description</Description>
<Providers>
<Provider>
<ProviderCode>1_M</ProviderCode>
<Qty>20</Qty>
</Provider>
<Provider>
<ProviderCode>1_D</ProviderCode>
<Qty>205</Qty>
</Provider>
<Provider>
<ProviderCode>2_M</ProviderCode>
<Qty>77</Qty>
</Provider>
<Provider>
<ProviderCode>2_D</ProviderCode>
<Qty>5</Qty>
</Provider>
<Provider>
<ProviderCode>3_M</ProviderCode>
<Qty>42</Qty>
</Provider>
<Provider>
<ProviderCode>4_M</ProviderCode>
<Qty>631</Qty>
</Provider>
</Providers>
</SKU>
</Inventory>
</Body>
</Message>
</Root>
使用XSLT:
<xsl:output method="xml" indent="yes"/>
<xsl:key name="validProviders" match="/Root/Providers/Result" use="ProviderCode"/>
<xsl:key name="validProviderQuality" match="/Root/Providers/Result" use="Quality"/>
<xsl:key name="inboundSkus" match="/Root/Message/Body/Inventory/SKU" use="SKU"/>
<xsl:template match="/">
<Root>
<xsl:apply-templates select="/Root/Items/Result"/>
</Root>
</xsl:template>
<xsl:template match="/Root/Items/Result">
<xsl:if test="key('inboundSkus',Sku)">
<SKU>
<xsl:variable name="Sku" select="Sku"/>
<xsl:for-each select="/Root/Providers/Result[generate-id(.)=generate-id(key('validProviderQuality',Quality)[1])]">
<Record>
<xsl:variable name="ProviderQuality" select="Quality" />
<xsl:element name="Sku"><xsl:value-of select="$Sku"/></xsl:element>
<xsl:element name="Quality"><xsl:value-of select="$ProviderQuality"/></xsl:element>
<xsl:element name="Qty1"><xsl:value-of select="sum(/Root/Message/Body/Inventory/SKU[SKU=$Sku]/Providers/Provider[ProviderCode=/Root/Providers/Result[Quality=$ProviderQuality]]/Qty)"/></xsl:element>
<xsl:element name="Qty2"><xsl:value-of select="sum(/Root/Message/Body/Inventory/SKU[SKU=$Sku]/Providers/Provider[key('validProviderQuality',$ProviderQuality)]/Qty)"/></xsl:element>
</Record>
</xsl:for-each>
</SKU>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
输出:
<?xml version="1.0" encoding="utf-8"?>
<Root>
<SKU>
<Record>
<Sku>ABC</Sku>
<Quality>Main</Quality>
<Qty1>0</Qty1>
<Qty2>980</Qty2>
</Record>
<Record>
<Sku>ABC</Sku>
<Quality>Damaged</Quality>
<Qty1>0</Qty1>
<Qty2>980</Qty2>
</Record>
</SKU>
</Root>
通缉结果
<Root>
<SKU>
<Record>
<Sku>ABC</Sku>
<Quality>Main</Quality>
<Qty>97</Qty>
</Record>
<Record>
<Sku>ABC</Sku>
<Quality>Damaged</Quality>
<Qty>210</Qty>
</Record>
</SKU>
</Root>
答案 0 :(得分:0)
我认为这个要求非常复杂,为了更好地理解它,我试图在XSLT 2.0中实现它。我没有时间尝试在XSLT 1.0中实现它,所以我将发布XSLT 2.0代码(你可以运行像Saxon 9或AltovaXML这样的XSLT 2.0处理器):
<xsl:stylesheet
version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:output indent="yes"/>
<xsl:variable name="wanted-skus" select="/Root/Items/Result/Sku"/>
<xsl:variable name="wanted-prvdrs" select="/Root/Providers/Result/ProviderCode"/>
<xsl:key name="qual" match="Root/Providers/Result" use="ProviderCode"/>
<xsl:template match="Root">
<xsl:copy>
<xsl:for-each-group
select="Message/Body/Inventory/SKU
[SKU = $wanted-skus]
/Providers/Provider[ProviderCode = $wanted-prvdrs]"
group-by="key('qual', ProviderCode)/Quality">
<Record>
<Sku><xsl:value-of select="ancestor::SKU/SKU"/></Sku>
<Quality><xsl:value-of select="current-grouping-key()"/></Quality>
<Qty><xsl:value-of select="sum(current-group()/Qty)"/></Qty>
</Record>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
使用该样式表Saxon 9.5转换输入
<?xml version="1.0" encoding="UTF-8"?>
<Root>
<Items>
<Result>
<Sku>XYZ</Sku>
</Result>
<Result>
<Sku>ABC</Sku>
</Result>
</Items>
<Providers>
<Result>
<ProviderCode>1_M</ProviderCode>
<Quality>Main</Quality>
</Result>
<Result>
<ProviderCode>1_D</ProviderCode>
<Quality>Damaged</Quality>
</Result>
<Result>
<ProviderCode>2_M</ProviderCode>
<Quality>Main</Quality>
</Result>
<Result>
<ProviderCode>2_D</ProviderCode>
<Quality>Damaged</Quality>
</Result>
</Providers>
<Message>
<Body>
<Inventory>
<SKU>
<SKU>AXYZ</SKU>
<Description>XYZ Description</Description>
<Providers>
<Provider>
<ProviderCode>1_M</ProviderCode>
<Qty>100</Qty>
</Provider>
<Provider>
<ProviderCode>2_M</ProviderCode>
<Qty>67</Qty>
</Provider>
<Provider>
<ProviderCode>2_D</ProviderCode>
<Qty>75</Qty>
</Provider>
<Provider>
<ProviderCode>3_M</ProviderCode>
<Qty>74</Qty>
</Provider>
<Provider>
<ProviderCode>4</ProviderCode>
<Qty>62</Qty>
</Provider>
</Providers>
</SKU>
<SKU>
<SKU>ABC</SKU>
<Description>ABC Description</Description>
<Providers>
<Provider>
<ProviderCode>1_M</ProviderCode>
<Qty>20</Qty>
</Provider>
<Provider>
<ProviderCode>1_D</ProviderCode>
<Qty>205</Qty>
</Provider>
<Provider>
<ProviderCode>2_M</ProviderCode>
<Qty>77</Qty>
</Provider>
<Provider>
<ProviderCode>2_D</ProviderCode>
<Qty>5</Qty>
</Provider>
<Provider>
<ProviderCode>3_M</ProviderCode>
<Qty>42</Qty>
</Provider>
<Provider>
<ProviderCode>4_M</ProviderCode>
<Qty>631</Qty>
</Provider>
</Providers>
</SKU>
</Inventory>
</Body>
</Message>
</Root>
进入想要的结果
<Root>
<Record>
<Sku>ABC</Sku>
<Quality>Main</Quality>
<Qty>97</Qty>
</Record>
<Record>
<Sku>ABC</Sku>
<Quality>Damaged</Quality>
<Qty>210</Qty>
</Record>
</Root>
答案 1 :(得分:0)
这里将样式表改编为xslt-1.0解决方案。 你可以试试这个:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="validProviderQuality" match="/Root/Providers/Result" use="Quality"/>
<xsl:variable name="mySkus" select="//Result/Sku" />
<xsl:template match="/">
<Root>
<xsl:apply-templates
select="/Root/Message/Body/Inventory/SKU[SKU = $mySkus]"/>
</Root>
</xsl:template>
<xsl:template match="/Root/Message/Body/Inventory/SKU" >
<xsl:variable name="Sku" select="SKU"/>
<xsl:for-each select="/Root/Providers/Result[generate-id(.)=
generate-id(key('validProviderQuality',Quality)[1])]">
<SKU>
<Record>
<xsl:variable name="ProviderQuality" select="Quality" />
<xsl:element name="Sku">
<xsl:value-of select="$Sku"/>
</xsl:element>
<xsl:element name="Quality">
<xsl:value-of select="$ProviderQuality"/>
</xsl:element>
<xsl:element name="Qty">
<xsl:value-of
select="sum(//SKU[SKU=$Sku]//Provider[
ProviderCode=/Root/Providers/Result[
Quality=$ProviderQuality
]/ProviderCode
]/Qty)"/>
</xsl:element>
</Record>
</SKU>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
将生成以下输出:
<?xml version="1.0"?>
<Root>
<SKU>
<Record>
<Sku>ABC</Sku>
<Quality>Main</Quality>
<Qty>97</Qty>
</Record>
</SKU>
<SKU>
<Record>
<Sku>ABC</Sku>
<Quality>Damaged</Quality>
<Qty>210</Qty>
</Record>
</SKU>
</Root>