2010-09-10 125 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

相關問題