How to extract the "for eached" element's child elements only with XSLT
I want to diplay a set of tables from an XML file defined as follows:
<reportStructure>
<table>
<headers>
<tableHeader>Header 1.1</tableHeader>
<tableHeader>Header 1.2</tableHeader>
</headers>
<tuples>
<tuple>
<tableCell>1.1.1</tableCell>
<tableCell>1.2.1</tableCell>
</tuple>
<tuple>
<tableCell>1.1.2</tableCell>
<tableCell>1.2.2</tableCell>
</tuple>
</tuples>
</table>
<table>
...
I am using XSLT and XPath to transform the data, but the foreach does not work the way I expect it to:
<xsl:template match="reportStructure">
<xsl:for-each select="table">
<table>
<tr>
<xsl:apply-templates select="/reportStructure/table/headers"/>
</tr>
<xsl:apply-templates select="/reportStructure/table/tuples/tuple"/>
</table>
</xsl:for-each>
</xsl:template>
<xsl:template match="headers">
<xsl:for-each select="tableHeader">
<th>
<xsl:value-of select="." />
</th>
</xsl:for-each>
</xsl:template
<xsl:template match="tuple">
<tr>
<xsl:for-each select="tableCell">
<td>
<xsl:value-of select="." />
</td>
</xsl:for-each>
</tr>
</xsl:template>
While I would expect this to output one table per table-tag, it outputs all the table headers and cells 开发者_JAVA百科for each table-tag.
You are selecting all headers and tuples in your apply-templates
.
Select the relevant ones only:
<xsl:template match="reportStructure">
<xsl:for-each select="table">
<table>
<tr>
<xsl:apply-templates select="headers"/>
</tr>
<xsl:apply-templates select="tuples/tuple"/>
</table>
</xsl:for-each>
</xsl:template>
You should really also simply have the above as a single table
template, without the xsl:for-each
:
<xsl:template match="table">
<table>
<tr>
<xsl:apply-templates select="headers"/>
</tr>
<xsl:apply-templates select="tuples/tuple"/>
</table>
</xsl:template>
Beside @Oded's good answer, this shows why a "push style" is more... reusable:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="table">
<table>
<xsl:apply-templates/>
</table>
</xsl:template>
<xsl:template match="headers|tuple">
<tr>
<xsl:apply-templates/>
</tr>
</xsl:template>
<xsl:template match="tableHeader">
<th>
<xsl:apply-templates/>
</th>
</xsl:template>
<xsl:template match="tableCell">
<td>
<xsl:apply-templates/>
</td>
</xsl:template>
</xsl:stylesheet>
精彩评论