在XSLT中将XML转换为HTML表

时间:2019-05-16 09:54:31

标签: html xml xslt

我正在尝试将XML转换为HTML表,但仍然与如何使用模板进行行列映射相混淆。我的XML定义是:

<Table>
  <Parent>
    <Head>Header 1</Head>
    <Children>
      <Node>Node 1</Node>
      <Node>Node 2</Node>
      <Node>Node 3</Node>
    </Children>
  </Parent>
  <Parent>
    <Head>Header 2</Head>
    <Children>
      <Node>Node 4</Node>
      <Node>Node 5</Node>
      <Node>Node 6</Node>
    </Children>
  </Parent>
</Table>

预期的HTML输出:

<table>
  <tr>
    <td>Header 1</td>
    <td>Header 2</td>
  </tr>
  <tr>
    <td>Node 1</td>
    <td>Node 4</td>
  </tr>
  <tr>
    <td>Node 2</td>
    <td>Node 5</td>
  </tr>
  <tr>
    <td>Node 3</td>
    <td>Node 6</td>
  </tr>
</table>

我使用了模板匹配,但是无法弄清楚如何按位置进行映射。这是我当前的XSLT代码:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output omit-xml-declaration="yes" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="Table">
    <table>
      <tr>
        <xsl:apply-templates select="Parent"/>
      </tr>
      <xsl:apply-templates select="Parent/Children"/>
    </table>
  </xsl:template>

  <xsl:template match="Parent">
    <td>
      <xsl:value-of select="Head"/>
    </td>
  </xsl:template>

  <xsl:template match="Parent/Children">
    <tr>
      <xsl:apply-templates/>
    </tr>
  </xsl:template>

  <xsl:template match="Parent/Children/Node">
    <td>
      <xsl:value-of select="."/>
    </td>
  </xsl:template>
</xsl:stylesheet>

1 个答案:

答案 0 :(得分:2)

如果可以假设每个Parent具有相同数量的节点,则可以通过仅选择第一个父节点的节点开始,因为它们将代表每个新行的开始

<xsl:apply-templates select="Parent[1]/Children/Node" mode="row"/>

(此处使用mode,因为最终的XSLT将具有多个与Node相匹配的模板)

然后,对于与这些节点匹配的模板,您将创建一个新的表行,并从XSLT中相同位置的所有父级中复制子级节点:

<xsl:template match="Node" mode="row">
  <tr>
    <xsl:apply-templates select="../../../Parent/Children/Node[position() = current()/position()]" />
  </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:strip-space elements="*"/>

  <xsl:template match="Table">
    <table>
      <tr>
        <xsl:apply-templates select="Parent"/>
      </tr>
      <xsl:apply-templates select="Parent[1]/Children/Node" mode="row"/>
    </table>
  </xsl:template>

  <xsl:template match="Parent">
    <td>
      <xsl:value-of select="Head"/>
    </td>
  </xsl:template>

  <xsl:template match="Node" mode="row">
    <xsl:variable name="pos" select="position()" />
    <tr>
      <xsl:apply-templates select="../../../Parent/Children/Node[position() = $pos]" />
    </tr>
  </xsl:template>

  <xsl:template match="Node">
    <td>
      <xsl:value-of select="."/>
    </td>
  </xsl:template>
</xsl:stylesheet>