我有一个示例XML,我想将其转换为HTML表,但表头应该来自XML元素, 例如:
看看附加的xml和xsl,我缺少的东西(我是XML世界的新手,现在展示一些数据,所以我必须用XML输出数据,并且在样式时XML看起来更好,因此所有这些练习)
<root>
<Device>
<Stat>
<Name>A</Name>
<Hardware>B</Hardware>
<Software>C</Software>
<Version>D</Version>
<State>E</State>
</Stat>
<Configuration>
<Up>
<Option1>2000</Option1>
<Option2>2500000</Option2>
<Option3>0</Option3>
<Option4>0</Option4>
<Option5>NA</Option5>
</Up>
<Down>
<Option1>2000</Option1>
<Option2>2500000</Option2>
<Option3>0</Option3>
<Option4>0</Option4>
<Option5>NA</Option5>
</Down>
</Configuration>
</Device>
<Device>
<Stat>
<Name>e</Name>
<Hardware>f</Hardware>
<Software>g</Software>
<Version>h</Version>
<State>i</State>
</Stat>
<Configuration>
<Up>
<Option1>2000</Option1>
<Option2>2500000</Option2>
<Option3>0</Option3>
<Option4>0</Option4>
<Option5>NA</Option5>
</Up>
<Down>
<Option1>2000</Option1>
<Option2>2500000</Option2>
<Option3>0</Option3>
<Option4>0</Option4>
<Option5>NA</Option5>
</Down>
</Configuration>
</Device>
</root>
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="/">
<table border="1">
<xsl:call-template name="tablesetup" />
<xsl:apply-templates />
</table>
</xsl:template>
<xsl:template name ="tablesetup">
<tr>
<th colspan="{count(/root/Stat/*)}">
<xsl:if test="Configuration[*]">
<xsl:attribute name="rowspan">2</xsl:attribute>
</xsl:if>
<xsl:text>Stat</xsl:text>
</th>
<xsl:if test="/root/Configuration[*]">
<th colspan="{count(/root/Configuration/*/*)}">
<xsl:text>Configuration</xsl:text>
</th>
</xsl:if>
</tr>
<tr>
<xsl:for-each select="/root/Configuration/*">
<th colspan="{count(*)}">
<xsl:value-of select="local-name()" />
</th>
</xsl:for-each>
</tr>
<tr>
<xsl:apply-templates select="/root/Stat/*" mode="header" />
<xsl:apply-templates select="/root/Configuration/*/*" mode="header" />
</tr>
<tr>
<xsl:apply-templates select="/root/Stat/*" mode="row" />
<xsl:apply-templates select="/root/Configuration/*/*" mode="row" />
</tr>
</xsl:template>
<xsl:template match="*" mode="header">
<th>
<xsl:value-of select="local-name()" />
</th>
</xsl:template>
<xsl:template match="*" mode="row">
<td>
<xsl:value-of select="." />
</td>
</xsl:template>
</xsl:stylesheet>
预期产出:
标题应该如下所示,然后在接下来的2行表数据中应该跟随,因为我们有2个'Device'元素
答案 0 :(得分:0)
对于标题单元格,而不是当前
<th colspan="{count(/root/Stat/*)}">
<xsl:if test="Configuration[*]">
<xsl:attribute name="rowspan">2</xsl:attribute>
</xsl:if>
<xsl:text>Stat</xsl:text>
</th>
您需要将其调整为仅检查第一个统计信息和配置单元格
<th colspan="{count(/root/Device[1]/Stat/*)}">
<xsl:if test="/root/Device[1]/Configuration[*]">
<xsl:attribute name="rowspan">2</xsl:attribute>
</xsl:if>
<xsl:text>Stat</xsl:text>
</th>
这假设所有 Stat 和配置元素具有相同的结构。 (否则会变得更难)
对于行,目前它确实
<tr>
<xsl:apply-templates select="Stat/*" mode="row" />
<xsl:apply-templates select="Configuration/*/*" mode="row" />
</tr>
而是将其替换为一行,以选择与您的行对应的单个设备元素:
<xsl:apply-templates select="Device" />
然后它在模板中与设备匹配,您输出行数据
<xsl:template match="Device">
<tr>
<xsl:apply-templates select="Stat/*" mode="row" />
<xsl:apply-templates select="Configuration/*/*" mode="row" />
</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:template match="/">
<table border="1">
<xsl:apply-templates name="root" />
</table>
</xsl:template>
<xsl:template match="root">
<tr>
<th colspan="{count(Device[1]/Stat/*)}">
<xsl:if test="Device[1]/Configuration[*]">
<xsl:attribute name="rowspan">2</xsl:attribute>
</xsl:if>
<xsl:text>Stat</xsl:text>
</th>
<xsl:if test="Device[1]/Configuration[*]">
<th colspan="{count(Device[1]/Configuration/*/*)}">
<xsl:text>Configuration</xsl:text>
</th>
</xsl:if>
</tr>
<tr>
<xsl:for-each select="Device[1]/Configuration/*">
<th colspan="{count(*)}">
<xsl:value-of select="local-name()" />
</th>
</xsl:for-each>
</tr>
<tr>
<xsl:apply-templates select="Device[1]/Stat/*" mode="header" />
<xsl:apply-templates select="Device[1]/Configuration/*/*" mode="header" />
</tr>
<xsl:apply-templates select="Device" />
</xsl:template>
<xsl:template match="*" mode="header">
<th>
<xsl:value-of select="local-name()" />
</th>
</xsl:template>
<xsl:template match="Device">
<tr>
<xsl:apply-templates select="Stat/*" mode="row" />
<xsl:apply-templates select="Configuration/*/*" mode="row" />
</tr>
</xsl:template>
<xsl:template match="*" mode="row">
<td>
<xsl:value-of select="." />
</td>
</xsl:template>
</xsl:stylesheet>
应用于XML时,输出以下内容
<table border="1">
<tr>
<th colspan="5" rowspan="2">Stat</th>
<th colspan="10">Configuration</th>
</tr>
<tr>
<th colspan="5">Up</th>
<th colspan="5">Down</th>
</tr>
<tr>
<th>Name</th>
<th>Hardware</th>
<th>Software</th>
<th>Version</th>
<th>State</th>
<th>Option1</th>
<th>Option2</th>
<th>Option3</th>
<th>Option4</th>
<th>Option5</th>
<th>Option1</th>
<th>Option2</th>
<th>Option3</th>
<th>Option4</th>
<th>Option5</th>
</tr>
<tr>
<td>A</td>
<td>B</td>
<td>C</td>
<td>D</td>
<td>E</td>
<td>2000</td>
<td>2500000</td>
<td>0</td>
<td>0</td>
<td>NA</td>
<td>2000</td>
<td>2500000</td>
<td>0</td>
<td>0</td>
<td>NA</td>
</tr>
<tr>
<td>e</td>
<td>f</td>
<td>g</td>
<td>h</td>
<td>i</td>
<td>2000</td>
<td>2500000</td>
<td>0</td>
<td>0</td>
<td>NA</td>
<td>2000</td>
<td>2500000</td>
<td>0</td>
<td>0</td>
<td>NA</td>
</tr>
</table>