在将动态xml数据解析为html表时,我遇到了一个问题。XML如下所示。
<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!很抱歉,我无法显示任何代码,因为它是在未连接的计算机上。
我在这里浏览了这么多问答,但对我的具体问题没有帮助。
提前感谢
注意:如果有人想出更简洁的格式,我可以以任何方式更改XML格式,使解析变得更容易。
发布于 2012-11-02 23:43:54
如果您使用的是XSLT1.0,则可以使用一种称为'Muenchian‘grouping的技术来获取不同的度量描述,这些描述将构成标题行的基础,还可用于输出每行的值。
首先,通过@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>对于每个result行,都会执行类似的操作,并迭代所有不同的度量值,但惟一的区别是您必须将当前的result元素作为参数传入,以供以后使用。
<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>https://stackoverflow.com/questions/13195702
复制相似问题