0
votes

I'm new to XSLT 1.0 , And I'm tring to merge/group two diffrent elements with the same value into a table.

XML input

<transaction>
    <request_id> 1 </request_id>
    <message> Hi </message>
</transaction>


<transaction>
    <response_id> 1 </response_id>
    <message> Hola </message>
</transaction>

<transaction>
    <request_id> 2 </request_id>
    <message> bye </message>
</transaction>

<transaction>
    <response_id> 2 </response_id>
    <message> bye bye </message>
</transaction>

I want to have the following table

<table>
    <thead>
        <th> ID </th>
        <th> request </th>
        <th> response </th>
    </thead>
    <tbody>
        <tr>
            <td> 1 </td>
            <td> Hi </td>
            <td> Hola </td>
        </tr>
        <tr>
            <td> 2 </td>
            <td> bye </td>
            <td> bye bye </td>
        </tr>
    </tbody>
</table>

I found here solutions for how to merge elements by value , but it always with the same element name, any suggestions?

1
Your subject says XSL 2.0, your text 1.0. So which version do you use?Martin Honnen
Will you always have (at most) two transactions - request and response - with the same id? -- Note also that your XML input must have a root element.michael.hor257k

1 Answers

0
votes

Given a well-formed input:

<root>
    <transaction>
        <request_id> 1 </request_id>
        <message> Hi </message>
    </transaction>

    <transaction>
        <response_id> 1 </response_id>
        <message> Hola </message>
    </transaction>

    <transaction>
        <request_id> 2 </request_id>
        <message> bye </message>
    </transaction>

    <transaction>
        <response_id> 2 </response_id>
        <message> bye bye </message>
    </transaction>
</root>

the following stylesheet:

XSLT 1.0

<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="response" match="transaction" use="response_id" />

<xsl:template match="/">
    <table>
        <thead>
            <th>ID</th>
            <th>Request</th>
            <th>Response</th>
        </thead>
        <tbody>
            <xsl:for-each select="root/transaction[request_id]">
                <tr>
                    <td><xsl:value-of select="request_id"/></td>
                    <td><xsl:value-of select="message"/></td>
                    <td><xsl:value-of select="key('response', request_id)/message"/></td>
                </tr>
            </xsl:for-each>
        </tbody>
    </table>
</xsl:template>

</xsl:stylesheet>

will return the requested result.

This assumes that every unique id has a pair of transactions (request and response).

The solution in this case is the same for XSLT 1.0 or 2.0.