将动态XML解析为html表
将动态xml数据解析为html表时遇到问题。 XML如下。将动态XML解析为html表
<results>
<result id="1" desc="Voltage and current">
<measure desc="VOLT" value="1.0" />
<measure desc="AMPERE" value="2.0" />
</result>
<result id="2" desc="Current-1">
<measure desc="AMPERE" value="5.0" />
</result>
</results>
从中我想像一个HTML表:
ID DESC VOLT AMPERE
1 Voltage and current 1.0 2.0
2 Current-1 5.0
通知在第二电压列中的空单元。 ID和DESC取自result/@ id和result/@ desc,其余列名应来自measure/@ desc
没有列名称应该重复,我设法编码那么远,但是当我开始添加我的措施,我需要将每个度量/ @ desc与表中正确的列匹配。我尝试使用双重嵌套循环来首先匹配所有唯一的列名称,然后再次循环所有度量以匹配列标题。但是xslt解析器向我扔了一个NPE! 对不起,我无法显示任何代码,因为它是在未连接的计算机上。
我浏览过这么多的Q/A,但对我的具体问题没有任何帮助。
在此先感谢
注:我能够以任何方式更改的XML格式,使之更容易分析,如果有人想出了一个更简洁的格式。
如果您使用的是XSLT1.0,则可以使用名为“Muenchian”分组的技术来获取不同的度量说明,这将形成首行的基础,并且还可用于输出每行的值。
首先,您需要定义一个关键通过@desc查找措施元素属性
<xsl:key name="measures" match="measure" use="@desc" />
然后,以获得不同的措施描述,你可以在措施重复出现元素首先在给定的组中@desc属性
<xsl:apply-templates
select="result/measure[generate-id() = generate-id(key('measures', @desc)[1])]"
mode="header" />
然后,对于您的标题,您只需要一个模板来输出描述。
<xsl:template match="measure" mode="header">
<th>
<xsl:value-of select="@desc" />
</th>
</xsl:template>
对于每个结果行,会做类似的事情,并遍历所有不同测量值,但唯一的区别是,你将不得不在当前结果元素作为参数传递,用于以后使用。
<xsl:apply-templates
select="/results/result/measure[generate-id() = generate-id(key('measures', @desc)[1])]"
mode="data">
<xsl:with-param name="result" select="." />
</xsl:apply-templates>
然后,在相匹配的措施此时模板,你可以在结果元素内访问措施具有匹配@desc属性(和ID没有这样的属性,没什么为单元输出)
<xsl:template match="measure" mode="data">
<xsl:param name="result" />
<td>
<xsl:value-of select="$result/measure[@desc = current()/@desc]/@value" />
</td>
</xsl:template>
这里是充分XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="measures" match="measure" use="@desc" />
<xsl:template match="/results">
<table>
<tr>
<th>ID</th>
<th>DESC</th>
<xsl:apply-templates select="result/measure[generate-id() = generate-id(key('measures', @desc)[1])]" mode="header" />
</tr>
<xsl:apply-templates select="result" />
</table>
</xsl:template>
<xsl:template match="result">
<tr>
<td><xsl:value-of select="@id" /></td>
<td><xsl:value-of select="@desc" /></td>
<xsl:apply-templates select="/results/result/measure[generate-id() = generate-id(key('measures', @desc)[1])]" mode="data">
<xsl:with-param name="result" select="." />
</xsl:apply-templates>
</tr>
</xsl:template>
<xsl:template match="measure" mode="header">
<th>
<xsl:value-of select="@desc" />
</th>
</xsl:template>
<xsl:template match="measure" mode="data">
<xsl:param name="result" />
<td>
<xsl:value-of select="$result/measure[@desc = current()/@desc]/@value" />
</td>
</xsl:template>
</xsl:stylesheet>
注意使用模式属性,因为您有两个模板匹配度量值元素,其功能方式不同。
当适用于您的XML输入,输出以下
<table>
<tr>
<th>ID</th>
<th>DESC</th>
<th>VOLT</th>
<th>AMPERE</th>
</tr>
<tr>
<td>1</td>
<td>Voltage and current</td>
<td>1.0</td>
<td>2.0</td>
</tr>
<tr>
<td>2</td>
<td>Current-1</td>
<td/>
<td>5.0</td>
</tr>
</table>
谢谢!优秀的答案! – styken
是否使用XSLT1.0或者XSLT2.0? –
我使用的是xslt 1.0 – styken