我有一个xml文件:
<PRODUCTS>
<PRODUCT>
<NAME_EN>jacket</NAME_EN>
<SKU>1</SKU>
<SIZE>
<CODE>01 </CODE>
<DESCRIPTION>34</DESCRIPTION>
</SIZE>
<COLOR>
<DESCRIPTION_EN>black</DESCRIPTION_EN>
</COLOR>
</PRODUCT>
<PRODUCT>
<NAME_EN>jacket</NAME_EN>
<SKU>2</SKU>
<SIZE>
<CODE>02</CODE>
<DESCRIPTION>35</DESCRIPTION>
</SIZE>
<COLOR>
<DESCRIPTION_EN>black</DESCRIPTION_EN>
</COLOR>
</PRODUCT>
<PRODUCT>
<NAME_EN>shoes</NAME_EN>
<SKU>3</SKU>
<SIZE>
<CODE>01</CODE>
<DESCRIPTION>34</DESCRIPTION>
</SIZE>
<COLOR>
<DESCRIPTION_EN>black</DESCRIPTION_EN>
</COLOR>
</PRODUCT>
</PRODUCTS>
我想使用xsl转换来实现这样的结果:
<catalog>
<product>
<variants>
<variant>
<sku>1</sku>
<options>
<option>
<code>size</code>
<value>34</value>
</option>
</options>
</variant>
<variant>
<sku>2</sku>
<options>
<option>
<code>size</code>
<value>35</value>
</option>
</options>
</variant>
</variants>
</product>
<product>
<variants>
<variant>
<sku>3</sku>
<options>
<option>
<code>size</code>
<value>34</value>
</option>
</options>
</variant>
</variants>
</product>
</catalog>
我需要的是 - NAME_EN
和COLOR/DESCRIPTION_EN
名称相同的所有节点上的每个节点。
我知道这样的每一个:
<xsl:for-each select="PRODUCTS/PRODUCT[NAME_EN='jacket']">
但它不会为我而烦恼。 有没有办法实现这个目标?
答案 0 :(得分:1)
以下是使用XSLT 1.0和Muenchian方法按照NAME_EN
字段的值对产品进行分组的解决方案。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="product-by-name" match="PRODUCT" use="NAME_EN"/>
<xsl:template match="/PRODUCTS">
<products>
<xsl:apply-templates select="PRODUCT"/>
</products>
</xsl:template>
<xsl:template match="PRODUCT">
<xsl:variable name="name-group" select="key('product-by-name', NAME_EN)"/>
<xsl:if test="generate-id() = generate-id($name-group[1])">
<product>
<variants>
<xsl:for-each select="$name-group">
<variant>
<xsl:apply-templates select="SKU"/>
<options>
<xsl:apply-templates select="SIZE"/>
</options>
</variant>
</xsl:for-each>
</variants>
</product>
</xsl:if>
</xsl:template>
<xsl:template match="SKU">
<sku><xsl:value-of select="."/></sku>
</xsl:template>
<xsl:template match="SIZE">
<option>
<code>size</code>
<value><xsl:value-of select="DESCRIPTION"/></value>
</option>
</xsl:template>
</xsl:stylesheet>
<强>输出强>
<products>
<product>
<variants>
<variant>
<sku>1</sku>
<options>
<option>
<code>size</code>
<value>34</value>
</option>
</options>
</variant>
<variant>
<sku>2</sku>
<options>
<option>
<code>size</code>
<value>35</value>
</option>
</options>
</variant>
</variants>
</product>
<product>
<variants>
<variant>
<sku>3</sku>
<options>
<option>
<code>size</code>
<value>34</value>
</option>
</options>
</variant>
</variants>
</product>
</products>
答案 1 :(得分:0)
我认为@Efrain是正确的,你所锁定的是分组。 &LT;的xsl:for-每个-组&gt;仅适用于xslt 2.0。 有关更多信息,请查看例如:how to apply group by on xslt elements
答案 2 :(得分:0)
以下是完整的解决方案:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="NAME_EN | DESCRIPTION_EN"/>
<xsl:template match="/">
<catalog>
<xsl:call-template name="product"/>
</catalog>
</xsl:template>
<xsl:template name="product">
<xsl:for-each-group select="//NAME_EN" group-by="text()">
<xsl:for-each select="current-grouping-key()">
<product>
<variants>
<xsl:for-each select="current-group()/parent::PRODUCT">
<variant>
<xsl:apply-templates/>
</variant>
</xsl:for-each>
</variants>
</product>
</xsl:for-each>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="SKU">
<sku>
<xsl:apply-templates/>
</sku>
</xsl:template>
<xsl:template match="SIZE">
<options>
<option>
<xsl:apply-templates/>
</option>
</options>
</xsl:template>
<xsl:template match="CODE">
<code>
<xsl:apply-templates/>
</code>
</xsl:template>
<xsl:template match="DESCRIPTION">
<value>
<xsl:apply-templates/>
</value>
</xsl:template>
</xsl:stylesheet>