2

使用 XSLT,当一列仅包含“0.00”或“-”时,我需要删除一个完整的表格列(标题 + 正文单元格)。

即,如果一列或多列的单元格中的所有值都是 0.00/-,则应删除整列。

4

2 回答 2

1

我假设您的意思不是说该列的所有数据单元格是否都是 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>
于 2012-08-31T00:26:20.367 回答
1

一、类似但更高效的 (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>

二、更高效(线性与 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>
于 2012-08-31T03:42:54.027 回答