Lorena
Lorena

Reputation: 135

Joining nodes from two different lists with xslt

I am working with the following xml format:

<Books>
    <Book Num="1">
        <Number>12335</Number>
        <Year>2011</Year>
        <Pages>400</Pages>
        <CustomerID>1</CustomerID>
    </Book>
    <Book Num="2">
        <Number>6954</Number>
        <Year>2001</Year>
        <Pages>40</Pages>
        <CustomerID>2</CustomerID>
    </Book>
</Books>
<Customers>
    <Customer Num="1">
        <Name>John</Name>
    </Customer>
    <Customer Num="2">
        <Name>Mary</Name>
    </Customer>
</Customers>

The books are connected to the customers by the CustomerID from book and the Num attribute on Customer. I made a table by iterating through the books, but need to add a column with the name of the customer that currently has it. I tried something like this, but with no success:

<xsl:for-each select="xml/Books/Book">
    <tr>
        <td>
            <xsl:value-of select="Number"></xsl:value-of>
        </td>
        <td>
            <xsl:value-of select="Year"></xsl:value-of>
        </td>
        <td>
            <xsl:value-of select="Pages"></xsl:value-of>
        </td>
        <td>
            <xsl:value-of select="xml/Customers/Customer[@Num = current()/@CustomerID]/Name"></xsl:value-of>
        </td>
    </tr>
</xsl:for-each>

Is there a way to achieve what I need?

Upvotes: 1

Views: 147

Answers (1)

Tim C
Tim C

Reputation: 70598

The problem is that your xsl:value-of is currently relative to the current Book node (i.e. it is looking for an xml element that is a child of the Book element), rather than looking from the start of the document again. You should add a / at the start of the expression.

Also, CustomerID is an element, not an attribute, so you shouldn't use @ before it.

Try this...

<xsl:value-of select="/xml/Customers/Customer[@Num = current()/CustomerID]/Name" />

Alternatively, you could make use of a xsl:key to look up the Customer elements by @Num

Try this XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="html" />

    <xsl:key name="cust" match="Customer" use="@Num" />

    <xsl:template match="/">
        <xsl:for-each select="xml/Books/Book">
            <tr>
                <td>
                    <xsl:value-of select="Number"></xsl:value-of>
                </td>
                <td>
                    <xsl:value-of select="Year"></xsl:value-of>
                </td>
                <td>
                    <xsl:value-of select="Pages"></xsl:value-of>
                </td>
                <td>
                    <xsl:value-of select="key('cust', CustomerID)/Name" />
                </td>
            </tr>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

Upvotes: 1

Related Questions