Конвертировать XML в HTML-таблицу в XSLT - PullRequest
0 голосов
/ 16 мая 2019

Я пытаюсь преобразовать свой 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 Ответ

2 голосов
/ 16 мая 2019

Если вы можете предположить, что каждый 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...