Chris Richardson
Chris Richardson

Reputation: 80

Join XML nodes with XSL

How can I join the /Document/Head/Signature node with the corresponding /Document/Image node using the docid field, in order to output the content to HTML in the same block?

<?xml version="1.0"?>
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Head>
        <Account>Fred123</Account>
        <accountName>Fred Blogs Ltd</accountName>
        <Signature>
            <sigName>Fred Bloggs</sigName>
            <docid>39215896554.0</docid>
        </Signature>
    </Head>
    <Image>
        <docid>39215896554.0</docid>
        <docTitle>Fred Bloggs Signature</docTitle>
    </Image>
    <Image>
        <docid>121212121212.0</docid>
        <docTitle>Jo Smith Signature</docTitle>
    </Image>
</Document>

Sample output:

<div id="sig">
    Signature Name: Fred Bloggs<br />
    Signature Title: Fred Bloggs Signature
</div>

I've tried a few methods using xsl:for-each but I've got something not quite right........ this was one attempt:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
    <html>
        <head>
        </head>
        <body>
            <h1>Page</h1>
            <xsl:for-each select="/Document/Head/Signature[docid = /Document/Image/docid]">
                <h4><xsl:value-of select="sigName"/></h4>
                <h4><xsl:value-of select="docTitle"/></h4>
            </xsl:for-each>
        </body>
    </html>
</xsl:template>

Upvotes: 0

Views: 148

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167716

You have the right condition, obviously then to output data from the referenced element you need to reference it again:

<xsl:template match="/">
    <html>
        <head>
        </head>
        <body>
            <h1>Page</h1>
            <xsl:for-each select="/Document/Head/Signature[docid = /Document/Image/docid]">
                <h4><xsl:value-of select="sigName"/></h4>
                <h4><xsl:value-of select="/Document/Image[docid = current()/docid]/docTitle"/></h4>
            </xsl:for-each>
        </body>
    </html>
</xsl:template>

I would use a key

<xsl:key name="image-ref" match="Image" use="docid"/>
<xsl:template match="/">
    <html>
        <head>
        </head>
        <body>
            <h1>Page</h1>
            <xsl:for-each select="/Document/Head/Signature[key('image-ref', docid)]">
                <h4><xsl:value-of select="sigName"/></h4>
                <h4><xsl:value-of select="key('image-ref', docid)/docTitle"/></h4>
            </xsl:for-each>
        </body>
    </html>
</xsl:template>

Upvotes: 2

Related Questions