我在XSLT表上遇到了一些麻烦。这是我的XML文档:
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<products>
<product>
<id>1</id>
</product>
</products>
<stocks>
<stock>
<id>1</id>
<size>S</size>
<store>NYC</store>
</stock>
<stock>
<id>1</id>
<size>L</size>
<store>NYC</store>
</stock>
<stock>
<id>1</id>
<size>S</size>
<store>LA</store>
</stock>
</stocks>
</catalog>
我想要的是拥有这种输出XML:
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<products>
<product>
<id>1</id>
<variants>
<variant>
<size>S</size>
<stocks>
<stock store-ref="NYC">
<stock store-ref="LA">
</stocks>
<variant>
<variant>
<size>L</size>
<stocks>
<stock store-ref="NYC">
</stocks>
<variant>
</variants>
</product>
</products>
</catalog>
今天,我正在使用这个XSLT来执行这种转换:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" exclude-result-prefixes="xs fn" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:key name="sizes" match="stock" use="id"/>
<xsl:key name="stocks" match="stock" use="fn:concat(id, '-', size)"/>
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<catalog>
<products>
<xsl:for-each select="/catalog/products/product">
<product>
<id><xsl:value-of select="id" /></id>
<variants>
<xsl:for-each select="key('sizes', id)">
<variant>
<size><xsl:value-of select="size" /></size>
<stocks>
<xsl:for-each select="key('stocks', fn:concat(id, '-', size))">
<stock store-ref="{store}" />
</xsl:for-each>
</stocks>
</variant>
</xsl:for-each>
</variants>
</product>
</xsl:for-each>
</products>
</catalog>
</xsl:template>
</xsl:stylesheet>
我得到了这个结果:
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<products>
<product>
<id>1</id>
<variants>
<variant>
<size>S</size>
<stocks>
<stock store-ref="NYC"/>
<stock store-ref="LA"/>
</stocks>
</variant>
<variant>
<size>L</size>
<stocks>
<stock store-ref="NYC"/>
</stocks>
</variant>
<variant>
<size>S</size>
<stocks>
<stock store-ref="NYC"/>
<stock store-ref="LA"/>
</stocks>
</variant>
</variants>
</product>
</products>
</catalog>
所以我的问题是我想选择不同的大小值,但它似乎不起作用。我已经尝试使用generate-id(),但我真的不明白它是如何工作的所以我没有得到很好的结果:( 知道如何解决这个问题吗? 谢谢!
答案 0 :(得分:2)
感谢@Tomalak,我找到了解决方案。这是我正在使用的XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" exclude-result-prefixes="xs fn" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:key name="sizes" match="stock" use="id"/>
<xsl:key name="stocks" match="stock" use="fn:concat(id, '-', size)"/>
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<catalog>
<products>
<xsl:for-each select="/catalog/products/product">
<product>
<id><xsl:value-of select="id" /></id>
<variants>
<xsl:for-each-group select="key('sizes', id)" group-by="size">
<variant>
<size><xsl:value-of select="size" /></size>
<stocks>
<xsl:for-each select="key('stocks', fn:concat(id, '-', size))">
<stock store-ref="{store}" />
</xsl:for-each>
</stocks>
</variant>
</xsl:for-each-group>
</variants>
</product>
</xsl:for-each>
</products>
</catalog>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
除了您自己找到的解决方案之外,我还想向您展示多级分组。
为方便起见,您只需要一个密钥:
<xsl:key name="kStock" match="stock" use="id"/>
和此:
<xsl:template match="product">
<xsl:copy>
<xsl:copy-of select="id" />
<variants>
<xsl:for-each-group select="key('kStock', id)" group-by="size">
<variant>
<xsl:copy-of select="size" />
<stocks>
<xsl:for-each-group select="current-group()" group-by="store">
<stock store-ref="{current-grouping-key()}" />
</xsl:for-each-group>
</stocks>
</variant>
</xsl:for-each-group>
</variants>
</xsl:copy>
</xsl:template>
请注意使用current-group()
和current-grouping-key()
。