我的问题与XML to HTML table with XSLT有点类似。
我在XML中定义了如下字典:
<dictionary>
<languages>
<language>en</language>
<language>ja</language>
</languages>
<entries>
<entry id="1">
<en>Test</en>
<ja>テスト</ja>
</entry>
<entry id="2">
<en>Test2</en>
<ja>テスト2</en>
</entry>
</entries>
</dictionary>
我想在XHTML中输出以下内容:
<table>
<thead>
<tr>
<th>en</th>
<th>ja</th>
</tr>
</thead>
<tbody>
<tr>
<td>Test</td>
<td>テスト</td>
</tr>
<tr>
<td>Test2</td>
<td>テスト2</td>
</tr>
</tbody>
</table>
我根据XML to HTML table with XSLT修改了答案如下:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="//dictionary/entries">
<table><xsl:apply-templates select="entry"/></table>
</xsl:template>
<xsl:template match="entry[1]">
<thead><tr><xsl:apply-templates select="*" mode="header"/></tr></thead>
<xsl:call-template name="standardRow"/>
</xsl:template>
<xsl:template match="entry" name="standardRow">
<tbody><tr><xsl:apply-templates select="*"/></tr></tbody>
</xsl:template>
<xsl:template match="entry/*">
<td><xsl:apply-templates select="node()"/></td>
</xsl:template>
<xsl:template match="entry/*" mode="header">
<th><xsl:value-of select="name()"/></th>
</xsl:template>
</xsl:stylesheet>
问题是我可能有如下输入:
<dictionary>
<languages>
<language>en</language>
<language>ja</language>
<language>id</language>
</languages>
<entries>
<entry id="1">
<en>Test</en>
<ja>テスト</ja>
</entry>
<entry id="2">
<ja>テスト2</ja>
<en>Test2</en>
<id>uji2</id>
</entry>
</entries>
</dictionary>
您可能已经理解,XSLT使用第一个entry
节点来定义列名,并且不生成列id
。此外,如果在entry
中更改了语言顺序,则<td>
不会按顺序显示。
根据上面的输入,我想要以下输出:
<table>
<thead>
<tr>
<th>en</th>
<th>ja</th>
<th>id</th>
</tr>
</thead>
<tbody>
<tr>
<td>Test</td>
<td>テスト</td>
<td></td>
</tr>
<tr>
<td>Test2</td>
<td>テスト2</td>
<td>Uji2</td>
</tr>
</tbody>
</table>
这是我第一次使用XSLT而我真的不知道如何做到这一点。我想我可以使用languages
节点。请注意,XML输入格式是灵活的,即使我需要更改格式,我也欢迎任何建议。
答案 0 :(得分:1)
以下是样式表示例:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="html" indent="yes"/>
<xsl:key name="k1" match="entry/*" use="concat(generate-id(..), '|', local-name())"/>
<xsl:variable name="languages" select="/dictionary/languages/language"/>
<xsl:template match="dictionary">
<xsl:apply-templates select="entries"/>
</xsl:template>
<xsl:template match="entries">
<table>
<thead>
<tr>
<xsl:apply-templates select="$languages" mode="header"/>
</tr>
</thead>
<tbody>
<xsl:apply-templates/>
</tbody>
</table>
</xsl:template>
<xsl:template match="language" mode="header">
<th>
<xsl:value-of select="."/>
</th>
</xsl:template>
<xsl:template match="entry">
<tr>
<xsl:apply-templates select="$languages">
<xsl:with-param name="entry" select="current()"/>
</xsl:apply-templates>
</tr>
</xsl:template>
<xsl:template match="language">
<xsl:param name="entry"/>
<td>
<xsl:value-of select="key('k1', concat(generate-id($entry), '|', .))"/>
</td>
</xsl:template>
</xsl:stylesheet>