2012-08-30 17 views
2

使用XSLT,我需要當列中只包含「0.00」或刪除一個完整的表列(標題+人體細胞)「 - 」。XSLT刪除表列當所有的價值

即,如果一列或多列的單元格中的所有值均爲0.00/- 則應刪除整列。

回答

1

我假定你mean't說,如果該列的所有數據單元是0.00/- 然後取出它,而不是隻是其中之一。如果我有誤解,請指教,我會更新相應的解決方案樣式表。

有很多不同的方式和選項來創建表,因此您的解決方案需要進行調整,以您的表的類型和結構。此處顯示的是簡單表格的解決方案。

XSLT 1.0解

這XSLT 1.0樣式表...

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

<xsl:template name="ident" match="@*|node()"> 
<xsl:copy> 
    <xsl:apply-templates select="@*|node()"/> 
</xsl:copy> 
</xsl:template> 

<xsl:template match="td"> 
    <xsl:variable name="col" select="count(preceding-sibling::td)+1" /> 
    <xsl:if test="../../tr/td[$col][. != '0.00'][. != '-']"> 
    <xsl:call-template name="ident" /> 
    </xsl:if> 
</xsl:template> 

</xsl:stylesheet> 

...當施加到該輸入文件...

<table> 
    <th> 
    <td>Contestant</td><td>Score</td><td>Country</td> 
    </th> 
    <tr> 
    <td>Jack</td><td>0.00</td><td>AUS</td> 
    </tr> 
    <tr> 
    <td>Jill</td><td>-</td><td>-</td> 
    </tr> 
</table> 

...將產量...

<table> 
    <th> 
    <td>Contestant</td> 
    <td>Country</td> 
    </th> 
    <tr> 
    <td>Jack</td> 
    <td>AUS</td> 
    </tr> 
    <tr> 
    <td>Jill</td> 
    <td>-</td> 
    </tr> 
</table> 

只有一列被刪除 - 一個包含所有「空」非標題單元格。

XSLT 2.0解決方案

這裏是XSLT 2.0當量...

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

<xsl:template match="@*|node()"> 
<xsl:copy> 
    <xsl:apply-templates select="@*|node()"/> 
</xsl:copy> 
</xsl:template> 

<xsl:template match="td[ not(
    for $c in count(preceding-sibling::td)+1 return 
    ../../tr/td[$c][.!='0.00'][.!= '-'] )]" /> 

</xsl:stylesheet> 
+0

你是神!非常感謝!我只需要對你的代碼進行一個簡單的複製/編輯,就可以刪除受到包含「0」或「 - 」的td影響的tgroup/colspecs,並且完成了。非常棒。非常感謝肖恩! – user1637261

+0

答案接受:) – user1637261

1

I.類似的但更有效(O(N))XSLT 1.0溶液(Sean的XSLT 1.0溶液是O(N^2),其中N是列數):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:ext="http://exslt.org/common" exclude-result-prefixes="ext"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:variable name="vrtfColProps"> 
    <xsl:for-each select="/*/tr[1]/td"> 
    <xsl:variable name="vPos" select="position()"/> 
    <col pos="{$vPos}"> 
      <xsl:if test="/*/tr/td[$vPos][not(. = 0.00 or . ='-')]"> 
      1 
      </xsl:if> 
     </col> 
     </xsl:for-each> 
</xsl:variable> 

<xsl:variable name="vColProps" select="ext:node-set($vrtfColProps)/*"/> 

<xsl:template match="node()|@*" name="identity"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="td"> 
    <xsl:variable name="vPos" select="position()"/> 
    <xsl:if test="$vColProps[@pos=$vPos]/node()"> 
    <xsl:call-template name="identity"/> 
    </xsl:if> 
</xsl:template> 
</xsl:stylesheet> 

當該變換被應用上下列文件

<table border="1"> 
    <th> 
    <tr> 
    <td>Contestant</td><td>Score</td><td>Country</td> 
    </tr> 
    </th> 
    <tr> 
    <td>Jack</td><td>0.00</td><td>AUS</td> 
    </tr> 
    <tr> 
    <td>Jill</td><td>-</td><td>-</td> 
    </tr> 
</table> 

想要的,正確的結果產生

<table border="1"> 
    <th> 
     <tr> 
     <td>Contestant</td> 
     <td>Country</td> 
     </tr> 
    </th> 
    <tr> 
     <td>Jack</td> 
     <td>AUS</td> 
    </tr> 
    <tr> 
     <td>Jill</td> 
     <td>-</td> 
    </tr> 
</table> 

II。更有效地(線性VS Sean的使用二次複雜性)XSLT 2.0溶液:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:variable name="vColProps"> 
    <xsl:for-each select="/*/tr[1]/td"> 
    <xsl:variable name="vPos" select="position()"/> 
    <col pos="{$vPos}"> 
      <xsl:if test="/*/tr/td[$vPos][not(. = '0.00' or . = '-')]"> 
      1 
      </xsl:if> 
     </col> 
     </xsl:for-each> 
</xsl:variable> 

<xsl:template match="node()|@*" name="identity"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match= 
"td[for $vPos in position() 
     return 
     not($vColProps/*[@pos=$vPos]/node()) 
    ]"/> 
</xsl:stylesheet> 

當這種轉化是在同一個XML文檔(上圖),同樣希望,正確的結果產生施加:

<table border="1"> 
    <th> 
     <tr> 
     <td>Contestant</td> 
     <td>Country</td> 
     </tr> 
    </th> 
    <tr> 
     <td>Jack</td> 
     <td>AUS</td> 
    </tr> 
    <tr> 
     <td>Jill</td> 
     <td>-</td> 
    </tr> 
</table> 
+0

感謝您指出了效率的提高。雖然承認這一點,但我在使用模板匹配條件中的position()方面存在問題。樣式表完美適用於示例文檔,但如果在行之間放置註釋,則轉換不會產生所需的結果。由於我們的輸入文檔是html,不僅僅是一些自定義的XML格式,這是一個合理的可能性。如果認爲,當輸入文檔是html時,更可靠的解決方案(之前的sibling :: style)將是可取的。 –

+0

@ SeanB.Durkin,其他元素的存在並不能證明效率低下的解決方案 - 在這種情況下修改此解決方案並保持線性效率是微不足道的。 –

+0

@ SeanB.Durkin,我已經用更高效的代碼更新了這個答案。 –