使用XSLT,当列只包含“0.00”或“ - ”时,我需要删除一个完整的表列(标题+正文单元格)。
即。如果一列或多列的单元格中的所有值都是0.00 / - 则应删除整列。
答案 0 :(得分:1)
我假设您不是要说列的所有数据单元格是否为0.00 / - 然后将其删除,而不是仅删除其中一个。如果我误解了,请通知我,我会相应地更新解决方案样式表。
创建表有很多不同的方法和选项,因此需要根据表的类型和结构调整解决方案。这里显示的是一种简单形式的表格的解决方案。
这个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的等价物......
<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>
答案 1 :(得分: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>
<强> II。更高效(线性与肖恩的二次复杂度)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>