我正在尝试将XML转换为HTML表,但仍然与如何使用模板进行行列映射相混淆。我的XML定义是:
<Table>
<Parent>
<Head>Header 1</Head>
<Children>
<Node>Node 1</Node>
<Node>Node 2</Node>
<Node>Node 3</Node>
</Children>
</Parent>
<Parent>
<Head>Header 2</Head>
<Children>
<Node>Node 4</Node>
<Node>Node 5</Node>
<Node>Node 6</Node>
</Children>
</Parent>
</Table>
预期的HTML输出:
<table>
<tr>
<td>Header 1</td>
<td>Header 2</td>
</tr>
<tr>
<td>Node 1</td>
<td>Node 4</td>
</tr>
<tr>
<td>Node 2</td>
<td>Node 5</td>
</tr>
<tr>
<td>Node 3</td>
<td>Node 6</td>
</tr>
</table>
我使用了模板匹配,但是无法弄清楚如何按位置进行映射。这是我当前的XSLT代码:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="Table">
<table>
<tr>
<xsl:apply-templates select="Parent"/>
</tr>
<xsl:apply-templates select="Parent/Children"/>
</table>
</xsl:template>
<xsl:template match="Parent">
<td>
<xsl:value-of select="Head"/>
</td>
</xsl:template>
<xsl:template match="Parent/Children">
<tr>
<xsl:apply-templates/>
</tr>
</xsl:template>
<xsl:template match="Parent/Children/Node">
<td>
<xsl:value-of select="."/>
</td>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:2)
如果可以假设每个Parent
具有相同数量的节点,则可以通过仅选择第一个父节点的节点开始,因为它们将代表每个新行的开始
<xsl:apply-templates select="Parent[1]/Children/Node" mode="row"/>
(此处使用mode
,因为最终的XSLT将具有多个与Node
相匹配的模板)
然后,对于与这些节点匹配的模板,您将创建一个新的表行,并从XSLT中相同位置的所有父级中复制子级节点:
<xsl:template match="Node" mode="row">
<tr>
<xsl:apply-templates select="../../../Parent/Children/Node[position() = current()/position()]" />
</tr>
</xsl:template>
尝试使用此XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="Table">
<table>
<tr>
<xsl:apply-templates select="Parent"/>
</tr>
<xsl:apply-templates select="Parent[1]/Children/Node" mode="row"/>
</table>
</xsl:template>
<xsl:template match="Parent">
<td>
<xsl:value-of select="Head"/>
</td>
</xsl:template>
<xsl:template match="Node" mode="row">
<xsl:variable name="pos" select="position()" />
<tr>
<xsl:apply-templates select="../../../Parent/Children/Node[position() = $pos]" />
</tr>
</xsl:template>
<xsl:template match="Node">
<td>
<xsl:value-of select="."/>
</td>
</xsl:template>
</xsl:stylesheet>