Convert XML to HTML Table in XSLT

放肆的年华 提交于 2021-01-29 10:30:58

问题


I'm trying to transform my XML to an HTML table but still quite confused with how to do row-column mapping using templates. My XML definition is:

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

Expected HTML output:

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

I've used template matching but can't figure out how to do the mapping by position. This is my current XSLT code:

<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:


If you can assume each Parent has the same number of nodes, you can start off by selecting just the nodes of the first Parent, as these will then represent the start of each new row

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

(The mode is used here, because the final XSLT will have multiple templates matching Node)

Then, for the template that matches these nodes, you create a new table row, and copy in the child nodes from all parents that in the same position in the XSLT:

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

Try this 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>


来源:https://stackoverflow.com/questions/56165779/convert-xml-to-html-table-in-xslt

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!