Lars
Lars

Reputation: 23

How do I merge data from 2 sequences and get one distinct sequence in XSLT?

I have a XML source similar to this:

<?xml version="1.0" encoding="utf-8"?>
<records>
    <record>
        <employee>
            <firstname>Tom</firstname>
            <lastname>Hanks</lastname>
        </employee>
        <boss firstname="Sylvester" lastname="Stallone">Sylvester</boss>
    </record>
    <record>
        <employee>
            <firstname>Tom</firstname>
            <lastname>Hanks</lastname>
        </employee>
        <boss firstname="Johnny" lastname="Depp">Johnny</boss>
    </record>
    <record>
        <employee>
            <firstname>Johnny</firstname>
            <lastname>Depp</lastname>
        </employee>
        <boss firstname="Robin" lastname="Williams">Robin</boss>
    </record>
</records>

And want to merge all the first names into one distinct list to be able to print something like this:

<root>
    <firstname>Tom</firstname>
    <firstname>Sylvester</firstname>
    <firstname>Johnny</firstname>
    <firstname>Robin</firstname>
</root>

I did some tests and I was finally able to merge everything into one string using this XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:template match="/">
        <root>
            <xsl:variable name="all_Users" select="records/record/employee/firstname" />
            <xsl:variable name="all_Values" select="records/record/boss" />

            <xsl:variable name="all_first_names" >
                <xsl:copy-of select="$all_Users"/>
                <xsl:copy-of select="$all_Values"/>
            </xsl:variable>

            <xsl:for-each select="$all_first_names"> 
                <firstname><xsl:value-of select="." /></firstname>
            </xsl:for-each>

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

Here's my result:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <firstname>TomTomJohnnySylvesterJohnnyRobin</firstname>
</root>

Is there a way to merge the sequences $all_Users and $all_Values into one sequence rather than a string?

Thank you very much in advance.

Upvotes: 0

Views: 54

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 117140

Why not simply:

XSLT 2.0

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

<xsl:template match="/records">
    <root>
        <xsl:for-each select="distinct-values(record/employee/firstname | record/boss/@firstname)">
            <firstname>
                <xsl:value-of select="." />
            </firstname>
        </xsl:for-each>
    </root>
</xsl:template>

</xsl:stylesheet>

Demo: https://xsltfiddle.liberty-development.net/6rexjij


P.S. The main problem with your attempt (other than not dealing with the distinct requirement) is that you do:

<xsl:for-each select="$all_first_names">

There is only one all_first_names variable. If you want to create an element for each of its nodes, you would need to do:

<xsl:for-each select="$all_first_names/node()">

Upvotes: 1

Related Questions