XML元素的HTML表头

时间:2014-07-04 11:26:00

标签: html xml xslt

我有一个示例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>

预期产出: enter image description here

标题应该如下所示,然后在接下来的2行表数据中应该跟随,因为我们有2个'Device'元素

1 个答案:

答案 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>