我有一些XML结构如下:
<report>
<columns>
<column col_id="col_1">Column 1 title</column>
<column col_id="col_2">Column 2 title</column>
<column col_id="col_3">Column 3 title</column>
</columns>
<rows>
<row>
<col_1>Value 1</col_1>
<!-- No col_2 value exists -->
<col_3>value 3</col_3>
</row>
<row>
<col_1>Value 1</col_1>
<col_2>Value 2</col_2>
<col_3>value 3</col_3>
<col_4>Value 4</col_4><!-- Not interested in this value -->
</row>
</rows>
</report>
我想使用XSLT将此数据输出为HTML表格。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="utf-8" indent="yes" />
<xsl:template match="Report">
<!-- Get the column names -->
<xsl:variable name="arr_columns" select="./columns/*" />
<div id="example_report" class="report">
<table style="width:100%">
<thead>
<tr class="header">
<!-- Columns first -->
<xsl:for-each select="$arr_columns">
<th><xsl:value-of select="." /></th>
</xsl:for-each>
</tr>
</thead>
<tbody>
<!-- Now the actual data -->
<xsl:for-each select="./rows/row">
<xsl:variable name="row" select="." />
<tr>
<xsl:for-each select="$arr_columns">
<xsl:variable name="col_id" select="./@column_id" />
<td><xsl:value-of select="$row/$col_id" /></td>
</xsl:for-each>
</tr>
</xsl:for-each>
</tbody>
</table>
</div>
</xsl:template>
</xsl:stylesheet>
我希望<xsl:value-of select="$row/$col_id" />
允许我根据存储在col_id变量中的名称选择列。但是,PHP的XSLTProcessor反而爆炸了,报告无法呈现。
PHP警告:XSLTProcessor :: transformToXml():没有与此对象关联的样式表
我尝试仅输出$ row(按预期输出整行作为字符串)和$ row / col_1(按预期输出col_1的内容),但尝试访问基于的节点变量的值似乎不起作用。如果我输出$ col_id的值,它会显示我想要输出的节点的名称,以便在循环中正确设置变量。
我猜这是可能的,我做错了,但我很难找到如何正确执行此操作的示例。我确实找到了允许您根据属性选择节点的示例,但正如您可以看到我没有属性的节点,它们的名称表示它们持有的内容。
有人可以帮助为这种情况编写正确的选择器吗?
为了完整性,这是我希望产生的输出:
<table>
<thead>
<tr>
<th>Column 1 title</th>
<th>Column 2 title</th>
<th>Column 3 title</th>
</tr>
</thead>
<tbody>
<tr>
<td>Value 1</td>
<td></td>
<td>value 3</td>
</tr>
<tr>
<td>Value 1</td>
<td>value 2</td>
<td>value 3</td>
</tr>
</tbody>
</table>
答案 0 :(得分:2)
以这种方式试试吗?
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="/report">
<xsl:variable name="columns" select="columns/column" />
<table style="width:100%">
<thead>
<tr>
<xsl:for-each select="$columns">
<th><xsl:value-of select="." /></th>
</xsl:for-each>
</tr>
</thead>
<tbody>
<xsl:for-each select="rows/row">
<xsl:variable name="current-row" select="." />
<tr>
<xsl:for-each select="$columns">
<td><xsl:value-of select="$current-row/*[local-name()=current()/@col_id]"/></td>
</xsl:for-each>
</tr>
</xsl:for-each>
</tbody>
</table>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:1)
特别是因为您在输入XML中的元素与目标HTML中的元素之间有这样清晰的映射,所以请考虑更加面向匹配的声明性方法,而不是当前基于程序的基于循环的方法:
[根据@ michael.hor257k的观察结果更新了匹配row
后的一些程序循环有助于满足省略的col_
单元格必须导致空{{}的要求1}}当关联的td
存在时。]
column