XSLT转换表格XML时colspec的@colwidth属性取值错误求解
问题描述
我在为colspec元素创建@colwidth属性及对应值时,出现所有@colwidth取值均重复拼接全部列宽值的问题。
输入XML
<tbl> <tblPr> <tblW w="5000" type="pct"/> </tblPr> <tblGrid> <gridCol/> <gridCol/> <gridCol/> </tblGrid> <tr> <tc> <tcPr> <tcW w="2450" type="pct"/> </tcPr> <p>Content here</p> </tc> <tc> <tcPr> <tcW w="50" type="pct"/> </tcPr> <p>Content here</p> </tc> <tc> <tcPr> <tcW w="2500" type="pct"/> </tcPr> <p>Payment at Maturity:</p> </tc> </tr> </tbl>
当前错误输出
<table> <tgroup cols="3"> <colspec colname="c1" colnum="1" colwidth="24.5%.5%25.0%"/> <colspec colname="c2" colnum="2" colwidth="24.5%.5%25.0%"/> <colspec colname="c3" colnum="3" colwidth="24.5%.5%25.0%"/> <tbody> <row> <entry> <p>Content Here</p> </entry> </row> <!--here all content will come--> </tbody> </tgroup> </table>
现有XSLT代码
<xsl:choose> <xsl:when test="not(@w:w)"> <xsl:attribute name="colwidth"> <xsl:for-each select="ancestor::w:tbl/w:tr/w:tc/w:tcPr/w:tcW"> <xsl:value-of select="concat(format-number(@w:w div 100,'#.##'), '%')"/> </xsl:for-each> </xsl:attribute> </xsl:when> <xsl:otherwise> <xsl:attribute name="colwidth"> <xsl:value-of select="concat(format-number(@w:w div number(ancestor::w:tbl/w:tblPr/w:tblW/@w:w) * 100,'#.##'), '%')"/> </xsl:attribute> </xsl:otherwise> </xsl:choose>
期望输出
<table> <tgroup cols="3"> <colspec colname="c1" colnum="1" colwidth="24.5%"/> <colspec colname="c2" colnum="2" colwidth="0.5%"/> <colspec colname="c3" colnum="3" colwidth="25.0%"/> <tbody> <row> <entry> <p>Content Here</p> </entry> </row> <!-- All content will come here--> </tbody> </tgroup> </table>
问题原因与修复方案
- 核心错误:现有代码的
xsl:when分支中,遍历了表格下所有行的所有单元格宽度属性,导致每生成一个colspec都会把所有列的宽度值拼接在一起,出现重复拼接问题。 - 格式错误:
format-number的格式串使用#.##时,整数位为0会自动省略,导致0.5%显示为.5%,需要把格式串调整为0.##保留整数位的0。
修正后的完整代码
处理gridCol生成colspec时,直接取当前列对应位置的第一行单元格宽度计算即可,不需要遍历所有单元格:
<xsl:choose> <xsl:when test="not(@w:w)"> <xsl:attribute name="colwidth"> <xsl:variable name="colPos" select="position()"/> <xsl:variable name="tcW" select="ancestor::w:tbl/w:tr[1]/w:tc[$colPos]/w:tcPr/w:tcW/@w:w"/> <xsl:value-of select="concat(format-number($tcW div 100,'0.##'), '%')"/> </xsl:attribute> </xsl:when> <xsl:otherwise> <xsl:attribute name="colwidth"> <xsl:value-of select="concat(format-number(@w:w div number(ancestor::w:tbl/w:tblPr/w:tblW/@w:w) * 100,'0.##'), '%')"/> </xsl:attribute> </xsl:otherwise> </xsl:choose>
内容的提问来源于stack exchange,提问作者Kita Ansari
相关产品推荐
相关产品推荐

