2010-09-10 250 views
1

我试图根据其孙节点的属性值向节点添加不同标签。xslt根据其孙子节点的属性值选择祖父节点节点

采样输入(1×3台):

<table> 
    <row> 
     <cell row="1" column="1" >heading text one</cell> 
    </row> 

    <row> 
     <cell row="2" column="1" >body text one</cell> 
    </row> 
    <row> 
     <cell row="3" column="1" >body text two</cell> 
    </row> 
</table> 

需要输出像这样:

<TableElmt> 
    <HeadingElmt> 
     <RowElmt> 
      <CellElmt>heading text one</CellElmt> 
     </RowElmt> 
    </HeadingElmt> 

    <BodyElmt> 
     <RowElmt> 
      <CellElmt>body text one</CellElmt> 
     </RowElmt> 
     <RowElmt> 
      <CellElmt>body text two</CellElmt> 
     </RowElmt> 
    </BodyElmt> 
</TableElmt> 

基本上,如果该行是一个基于@row标题行我只能决定细胞的元素。

这是我已经试过:

<xsl:template name="matcheverything" match="table"> 
    <xsl:apply-templates select="row" /> 
</xsl:template> 

<xsl:template name="matchheadings" match="table[*/*/@row=1]"> 
    <BodyElmt> 
     <xsl:apply-templates select="row" /> 
    </BodyElmt> 
</xsl:template> 

<xsl:template match="row"> 
    <xsl:choose> 
     <xsl:when test="*/@row=1"> 
      <HeadingElmt><RowElmt> 
       <xsl:apply-templates select="cell"/> 
      </RowElmt></HeadingElmt> 
     </xsl:when> 
     <xsl:otherwise> 
      <RowElmt> 
       <xsl:apply-templates select="cell"/> 
      </RowElmt> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

<xsl:template match="cell"> 
    <CellElmt><xsl:apply-templates select="*"/></CellElmt> 
</xsl:template> 

我在想“matchheadings”模板,有一个更具体的匹配要求,应该认识到标题行,但它在表格中的实际匹配的每一行。

所以我的实际出从这个样式表是把作为标题行处理每一行 - 很不好:(

<TableElmt> 
    <HeadingElmt> 
     <RowElmt> 
      <CellElmt>heading text one</CellElmt> 
     </RowElmt> 

     <RowElmt> 
      <CellElmt>body text one</CellElmt> 
     </RowElmt> 
     <RowElmt> 
      <CellElmt>body text two</CellElmt> 
     </RowElmt> 
    </HeadingElmt> 
</TableElmt> 
+0

问得好(+1)。请参阅我的答案,以获得完全“推式”XSLT解决方案:) – 2010-09-10 19:44:13

回答

1

该转化

<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"> 
    <TableElmt> 
    <xsl:apply-templates/> 
    </TableElmt> 
</xsl:template> 

<xsl:template match="row[cell/@row='1']"> 
    <HeadingElmt> 
    <xsl:apply-templates select="." mode="copy"/> 
    </HeadingElmt> 
</xsl:template> 

<xsl:template match="row[cell[not(@row='1')]][1]"> 
    <BodyElmt> 
    <xsl:apply-templates select=".|following-sibling::row" mode="copy"/> 
    </BodyElmt> 
</xsl:template> 

<xsl:template match="row" mode="copy"> 
    <RowElmt> 
    <xsl:apply-templates/> 
    </RowElmt> 
</xsl:template> 

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

<xsl:template match="row"/> 
</xsl:stylesheet> 

当所提供的XML文档施加:

<table> 
    <row> 
     <cell row="1" column="1" >heading text one</cell> 
    </row> 
    <row> 
     <cell row="2" column="1" >body text one</cell> 
    </row> 
    <row> 
     <cell row="3" column="1" >body text two</cell> 
    </row> 
</table> 

产生想要的,正确的结果

<TableElmt> 
    <HeadingElmt> 
     <RowElmt> 
      <CellElmt>heading text one</CellElmt> 
     </RowElmt> 
    </HeadingElmt> 
    <BodyElmt> 
     <RowElmt> 
      <CellElmt>body text one</CellElmt> 
     </RowElmt> 
     <RowElmt> 
      <CellElmt>body text two</CellElmt> 
     </RowElmt> 
    </BodyElmt> 
</TableElmt> 
+0

这正是我正在寻找的。 我想我缺少mode =“copy”并测试“row [cell/@ row ='1']”和“row [cell [not(@ row ='1')]]”。非常感谢! – highlightall 2010-09-10 20:13:28

1

编辑:它看起来像我错过了这个

基本上我只能确定行 是基于单元的@row 元素的标题行。

该样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="table"> 
     <TableElmt> 
      <HeadingElmt> 
       <xsl:apply-templates select="row[cell/@row=1]"/> 
      </HeadingElmt> 
      <BodyElmt> 
       <xsl:apply-templates select="row[cell/@row!=1]"/> 
      </BodyElmt> 
     </TableElmt> 
    </xsl:template> 
    <xsl:template match="row"> 
     <RowElmt> 
      <xsl:apply-templates/> 
     </RowElmt> 
    </xsl:template> 
    <xsl:template match="cell"> 
     <CellElmt> 
      <xsl:apply-templates/> 
     </CellElmt> 
    </xsl:template> 
</xsl:stylesheet> 

输出:

<TableElmt> 
    <HeadingElmt> 
     <RowElmt> 
      <CellElmt>heading text one</CellElmt> 
     </RowElmt> 
    </HeadingElmt> 
    <BodyElmt> 
     <RowElmt> 
      <CellElmt>body text one</CellElmt> 
     </RowElmt> 
     <RowElmt> 
      <CellElmt>body text two</CellElmt> 
     </RowElmt> 
    </BodyElmt> 
</TableElmt> 
+0

工作得很好,谢谢!我没有想过测试我的行索引..但它在这种情况下绝对有效。 – highlightall 2010-09-10 19:54:38

+0

@highlightall:你好! – 2010-09-10 20:06:45

相关问题