XSLT и рекурсия для генерации таблицы - PullRequest
0 голосов
/ 13 октября 2018

Я новичок в XSLT, и у меня возникли некоторые проблемы при попытке отформатировать документ XML с рекурсивными узлами.

Существует 2 стиля узла дерева: группа и данные.

Проблема заключается в том, что мой текущий шаблон XSLT не может генерировать содержимое, когда узлы смешаны по группам и стилям данных.

XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="html" indent="yes"/>
  <xsl:template match="Nodes[TreeNode]">
      <xsl:apply-templates select="TreeNode" />
  </xsl:template>

  <xsl:template match="Nodes[not(TreeNode)]" />

  <xsl:template match="TreeNode[Style='Data']">
      <!--<table>
        <thead>
          <tr>
            <th scope="col">Value</th>
         </tr>
        </thead>
        <tbody>-->
          <tr>
            <td>
              <xsl:value-of select="Value"/>
            </td>
          </tr>
        <!--</tbody>
      </table>-->
  </xsl:template>

   <xsl:template match="TreeNode[Style='Group']">
    <group>
      <p>
        <xsl:value-of select="Label"/>
      </p> 
         <xsl:apply-templates select="Nodes" />
    </group>
   </xsl:template>
</xsl:stylesheet>

XML

<?xml version="1.0" encoding="utf-8"?>
<TreeNode xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Label>Root</Label>
  <Style>Group</Style>
  <Nodes>
    <TreeNode>
      <Label>A</Label>
      <Style>Group</Style>
      <Nodes>
        <TreeNode>
          <Label>B</Label>
          <Style>Group</Style>
          <Nodes>
            <TreeNode>
              <Label />
              <Value>AAA</Value>
              <Style>Data</Style>
              <Nodes />
            </TreeNode>
            <TreeNode>
              <Label />
              <Value>BBB</Value>
              <Style>Data</Style>
              <Nodes />
            </TreeNode>
          </Nodes>
        </TreeNode>
        <TreeNode>
          <Label>C</Label>
          <Style>Group</Style>
          <Nodes>
            <TreeNode>
              <Label />
              <Value>CCC</Value>
              <Style>Data</Style>
              <Nodes />
            </TreeNode>
            <TreeNode>
              <Label />
              <Value>DDD</Value>
              <Style>Data</Style>
              <Nodes />
            </TreeNode>
          </Nodes>
        </TreeNode>
        <TreeNode>
          <Label>D</Label>
          <Style>Group</Style>
          <Nodes>
            <TreeNode>
              <Label />
              <Value>EEE</Value>
              <Style>Data</Style>
              <Nodes />
            </TreeNode>
          </Nodes>
        </TreeNode>
      </Nodes>
    </TreeNode>
  </Nodes>
</TreeNode>

ОжидаетсяРезультат:

enter image description here

1 Ответ

0 голосов
/ 13 октября 2018

У вас есть два шаблона в начале вашего XSLT

<xsl:template match="Nodes[TreeNode]">
  <xsl:apply-templates select="TreeNode" />
</xsl:template>

<xsl:template match="Nodes[not(TreeNode)]" />

Они могут быть объединены в один;вот так:

<xsl:template match="Nodes">
  <xsl:apply-templates select="TreeNode" />
</xsl:template>

Причина в том, что если Nodes не имеет TreeNode, то <xsl:apply-templates select="TreeNode" /> ничего не выберет, так что эффект тот же.(На самом деле, вы можете полностью удалить этот шаблон, если Nodes может содержать только TreeNode, поскольку встроенные шаблоны XSLT будут делать то же самое).

Однако, в ответ на вашу проблемуЭто то, что я думаю, что вам нужен еще один шаблон, который вам нужен другой шаблон, который соответствует Nodes в случае, когда есть дочерний TreeNode для «Данные»

<xsl:template match="Nodes[TreeNode/Style='Data']">
  <table>
    <xsl:apply-templates select="TreeNode" />
  </table>
</xsl:template>

Попробуйте этот XSLT

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

  <xsl:template match="Nodes[TreeNode/Style='Data']">
      <table>
        <xsl:apply-templates select="TreeNode" />
      </table>
  </xsl:template>

  <xsl:template match="Nodes">
    <xsl:apply-templates select="TreeNode" />
  </xsl:template>

  <xsl:template match="TreeNode[Style='Data']">
    <tr>
      <td>
        <xsl:value-of select="Value"/>
      </td>
    </tr>
  </xsl:template>

   <xsl:template match="TreeNode[Style='Group']">
    <group>
      <p>
        <xsl:value-of select="Label"/>
      </p> 
      <xsl:apply-templates select="Nodes" />
    </group>
   </xsl:template>
</xsl:stylesheet>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...