Merging set of elements based on a common attribute in XSLT 1.0

荒凉一梦 提交于 2019-12-18 09:45:44

问题


I m working with XSLT1.0 . My requirement is to merge set of elements based on a common attribute. I ve an xml which looks like this:

<?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>

I want the output XML as below

<?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>

Have tried using but couldnt achieve the correct output. Pls let me know if this kind of transformation is possible and how it can be done. Appreciate your help!


回答1:


As shown in the other topic halfbit linked to, you need to use a key in order to (1) select distinct products (aka the Muenchian method) and (2) collect the values from the related group.

Here's a little more readable (IMHO) version:

<?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>

If your processor is EXSLT capable, you can use the set:distinct() function instead of the Muenchian grouping.



来源:https://stackoverflow.com/questions/20262560/merging-set-of-elements-based-on-a-common-attribute-in-xslt-1-0

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!