2012-10-18 77 views
0

我有一个问题,我需要从XML生成HTML,我可以有多个嵌套在对方的标签。我如何通过递归来传递它们?Xslt递归与动态XML

这里是从XML样本:

<rows> 
    <row> 
     <cell>1</cell> 
     <cell>2</cell> 
     <cell>1</cell> 
     <cell>2</cell> 
     <row> 
     <cell>3</cell> 
     <cell>4</cell> 
      <row> 
       <cell>5</cell> 
       <cell>6</cell> 
       <cell>6</cell> 
      </row> 
     </row> 
    </row> 
</rows> 

我的XSLT是:

<table> 
     <th>1</th><th>2</th>3<th>4</th><th>5</th> 
     <xsl:for-each select="rows/row"> 
     <tr> 
      <xsl:for-each select="cell"> 
      <td> 
       <xsl:value-of select="."/> 
      </td> 
      </xsl:for-each> 
     </tr> 
     <xsl:for-each select="row"> 
      <tr> 
      <xsl:for-each select="cell"> 
       <td> 
       <xsl:value-of select="."/> 
       </td> 
      </xsl:for-each> 
      </tr> 
     </xsl:for-each>  
     </xsl:for-each> 
    </table> 

所以现在我的问题是我怎么能显示每行中的所有atributes?

编辑:从XSLT生成HTML

<html><body> 
<table> 
<th>1</th> 
<th>2</th> 
<th>3</th> 
<th>4</th> 
<th>5</th> 

<tr> 
<td>1</td> 
<td>2</td> 
<td>1</td> 
<td>2</td> 
</tr> 
<tr> 
<td>3</td> 
<td>4</td> 
</tr> 
</table> 
</body></html> 

第二个编辑:

XSLT:

<xsl:template match="cell"> 


    <td style="overflow:hidden;border:1px solid black;"> 
     <div style="width:100px;height:20px;margin-bottom: 10px;margin-top: 10px;"> 

      <xsl:variable name="id1" select="row/@id"/> 

      <xsl:if test="starts-with(id1, 'Dir')"> 
       <xsl:value-of select="cell/@image"/> 
      </xsl:if> 

      <xsl:value-of select="."/> 


     </div> 
     </td> 

    </xsl:template> 

XML:

<row id="Dir_44630"> 
    <cell>Text</cell> 
    <cell>1</cell> 
    <cell>1.00</cell> 
    <cell>3</cell> 
    <cell 4</cell> 
    <cell>5</cell> 
    <cell>6</cell> 
    <cell>7</cell> 
</row> 
+3

不要使用'for-each',它会让你生气。 XSLT是一种声明性语言。将样式表基于模板而非循环要容易得多。另外,你的意思是什么?您的示例输入中没有任何内容或输出。 – toniedzwiedz

+0

通过属性我的意思是获取单元格值:1,2,3,4,5和6. – Aleks

+2

您可以显示此文档所需的输出吗?我不确定你想要达到什么目的。 – toniedzwiedz

回答

1

首先,在你的情况,你将开始有一个模板来匹配您的根元素

<xsl:template match="/rows"> 

在此,你将不得不代码来构建你的表头,然后开始寻找孩子元素

<xsl:template match="/rows"> 
    <table> 
     <!-- Header --> 
     <xsl:apply-templates select="row"/> 
    </table> 
</xsl:template> 

你会然后有一个模板匹配元素,因此您可以输出tr元素,然后查找单个单元格

<xsl:template match="row"> 
    <tr> 
     <xsl:apply-templates select="cell"/> 
    </tr> 
    <xsl:apply-templates select="row"/> 
</xsl:template> 

注意递归调用继续寻找行被嵌套在当前元素元素。

同样,你将有一个模板来匹配细胞元素,这将只是输出TD元素,单元格的值。

我不确定的唯一的事情是你的规则应该输出哪些行。看起来您不想输出嵌套两个或更多级别的元素。在这种情况下,你可以添加一个模板,忽略其中至少有两个或两个以上行是祖先行

<xsl:template match="row[ancestor::row[2]]"/> 

以下是完整的XSLT

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

    <xsl:template match="/rows"> 
     <table> 
     <tr> 
      <th>1</th> 
      <th>2</th> 
      <th>3</th> 
      <th>4</th> 
      <th>5</th> 
     </tr> 
     <xsl:apply-templates select="row"/> 
     </table> 
    </xsl:template> 

    <xsl:template match="row"> 
     <tr> 
     <xsl:apply-templates select="cell"/> 
     </tr> 
     <xsl:apply-templates select="row"/> 
    </xsl:template> 

    <xsl:template match="row[ancestor::row[2]]"/> 

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

当适用于您的示例XML,以下输出

<table> 
    <tr> 
     <th>1</th> 
     <th>2</th> 
     <th>3</th> 
     <th>4</th> 
     <th>5</th> 
    </tr> 
    <tr> 
     <td>1</td> 
     <td>2</td> 
     <td>1</td> 
     <td>2</td> 
    </tr> 
    <tr> 
     <td>3</td> 
     <td>4</td> 
    </tr> 
</table> 

编辑:如果你想在模板中的一行访问属性元素的匹配细胞元素,你需要指定它的父元素,像这样

<xsl:variable name="id1" select="../@id"/> 

select="row/@id"实际上将寻找一个行,它是当前电池元件的孩子。

+0

非常感谢您这样做,但是现在我在显示图像时出现了一个问题,当该行具有以Dir开头的id时,如果发生这种情况,我需要在第一个单元格数据旁边打印图像。我是xslt中的新成员,很难理解它是如何工作的。我已将我的示例放在第二个编辑中。 – Aleks

+0

问问题没有问题,但你应该问一个全新的问题。如果您在回答问题后根据新的要求编辑问题,会变得困惑。尽管开始一个新的问题是完全正确的。 –

+0

xml和完整的解决方案显示在这里,所以我认为这将是更容易为大家解决第二个问题,我知道这个问题已经得到了一种大,所以这将是我最后一次编辑我保证:)。 – Aleks