简体   繁体   中英

Using arrays in XSLT 1.0 to build a table with uneven number of rows

I have an XML structure such as the following:

<people>
    <attending>
        <person><firstname>John</firstname><lastname>Doe</lastname></person>
        <person><firstname>George</firstname><lastname>Washington</lastname></person>
        <person><firstname>Henry</firstname><lastname>Dodson</lastname></person>
    </attending>
    <maybe>
        <person><firstname>Jackie</firstname><lastname>Gleason</lastname></person>
        <person><firstname>Jill</firstname><lastname>Hill</lastname></person>
    </maybe>
</people>

I want to build a single HTML table using XSLT 1.0 with the information in both attending and maybe elements, but they are never guaranteed to have the same amount of elements. I'd like the table to look like this (or similar):

<table>
    <tr>
        <th>Attending</th><th>Maybe</th>
    </tr>
    <tr>
        <td>John Doe</td><td>Jackie Gleason</td>
    </tr>
    <tr>
        <td>George Washington</td><td>Jill Hill</td>
    </tr>
    <tr>
        <td>Henry Dodson</td><td>&nbsp;</td>
    </tr>
</table>

So since I can only do an xsl:for-each over one element at a time, I could build two separate tables (one column at a time), and put each table in two cells side-by-side of a larger, encompassing table. But, I need one table . (If you'd like to know why, it's for cross-browser styling reasons, and tables within tables become difficult to control cross browser. One table would alleviate a lot of this.)

The next obvious thing would be to build two arrays, one with the attending node-set and one with the maybe node-set, then do an index based xsl:for-each where I look up the index in each array, because of course HTML tables need to be built one row at a time, but unfortunately my data is stored as columns. Also, the XSLT doesn't know beforehand how many of each attending or maybe there will be, so it has to be able to dynamically handle it.

  • Does XSLT 1.0 support such arrays?
  • How do I do a xsl:for-each iteration over such arrays? (As in $attending[index] where index is my "for each" counter)

I would prefer answers for XSLT 1.0 since that is the framework I am constrained to, but I am open to hearing about how this could be done in later versions of XSLT.

Here's one way you could look at it:

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:template match="/people">
    <table>
        <tr>
            <th>Attending</th>
            <th>Maybe</th>
        </tr>       
        <xsl:call-template name="rows"/>
    </table>
</xsl:template>

<xsl:template name="rows">
    <xsl:param name="i" select="1"/>
    <xsl:if test="*/person[$i]">
        <tr>
            <td>
                <xsl:apply-templates select="attending/person[$i]"/>
            </td>
            <td>
                <xsl:apply-templates select="maybe/person[$i]"/>
            </td>
        </tr>
        <xsl:call-template name="rows">
            <xsl:with-param name="i" select="$i + 1"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

<xsl:template match="person">
    <xsl:value-of select="firstname"/>
    <xsl:text> </xsl:text>
    <xsl:value-of select="lastname"/>
</xsl:template>

</xsl:stylesheet>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM