基于XSLT 1.0中的公共属性合并元素集

时间:2013-11-28 09:43:53

标签: xml xslt xslt-1.0

我正在使用XSLT1.0。我的要求是基于公共属性合并元素集。 我有一个看起来像这样的xml:

<?xml version="1.0" encoding="utf-8"?>
<Catalog>
    <product>
        <productId>S100</productId>
        <name>RNKC</name>
        <category>books</category>
    </product>
    <product>
        <productId>S100</productId>
        <name>RNKC</name>
        <category>CD</category>
    </product>
    <product>
        <productId>S200</productId>
        <name>ISDR</name>
        <category>eBook</category>
    </product>
    <product>
        <productId>S200</productId>
        <name>ISDR</name>
        <category>books</category>
    </product>
</Catalog>

我希望输出XML如下所示

<?xml version="1.0" encoding="utf-8"?>
<Catalog>
    <product>
        <productId>S100</productId>
        <name>RNKC</name>
        <category>books,CD</category>
    </product>
    <product>
        <productId>S200</productId>
        <name>RNKC</name>
        <category>eBook,books</category>
    </product>
</Catalog>

尝试使用但无法实现正确的输出。请告诉我这种转变是否可行以及如何实现。 感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

如另一个主题中所示的半字节所示,您需要使用一个键以便(1)选择不同的产品(也称为Muenchian方法)和(2)从相关组中收集值。

这是一个更具可读性(恕我直言)的版本:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />

<xsl:key name="sameProduct" match="product" use="productId" />

<xsl:template match="/">

<!-- SELECT ONLY THE FIRST PRODUCT IN EACH GROUP -->
<xsl:for-each select="Catalog/product[generate-id() = generate-id(key('sameProduct', productId)[1])]">
<product>
    <productId><xsl:value-of select="productId"/></productId>
    <name><xsl:value-of select="name"/></name>
    <category>
        <!-- GET THE VALUES FROM ALL MEMBERS OF THE GROUP -->
        <xsl:for-each select="key('sameProduct', productId)">
            <xsl:value-of select="category"/>
            <xsl:if test="position() != last()">
                <xsl:text>,</xsl:text>
            </xsl:if>
        </xsl:for-each>
    </category>
</product>
</xsl:for-each>

</xsl:template>
</xsl:stylesheet>

如果您的处理器支持EXSLT,则可以使用set:distinct()函数代替Muenchian分组。