基于colspan和rowspan的XML表格行/列缺失XSLT验证需求
表格列/行完整性的XSLT验证需求
待验证的XML表格代码
<table-wrap id="tbl4" position="float"> <label>Table E3</label> <caption> <p></p> </caption> <alternatives> <graphic xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="EEMCS-01-2021-001110.tif"/> <table frame="hsides"> <colgroup> <col align="left"/> <col align="left"/> <col align="left"/> <col align="left"/> <col align="left"/> <col align="left"/> <col align="left"/> </colgroup> <thead> <tr> <th rowspan="2" align="left">1</th> <th colspan="4" align="center">2</th> <th rowspan="2" align="center">3</th> </tr> <tr> <th align="center">4</th> <th align="center">5</th> <th align="center">6</th> <th align="center">7</th> <th align="center">8</th> </tr> </thead> <tbody> <tr> <td>9</td> <td rowspan="2">10</td> <td>11</td> <td>12</td> <td>13</td> <td>14</td> <td rowspan="2">15</td> </tr> <tr> <td>16</td> <td>17</td> <td>18</td> <td>19</td> <td>20</td> </tr> <tr> <td>21</td> <td colspan="2">22</td> <td rowspan="2">23</td> <td colspan="2">24</td> <td>25</td> </tr> <tr> <td>26</td> <td>27</td> <td>28</td> <td>29</td> <td>30</td> <td>31</td> </tr> <tr> <td rowspan="2">32</td> <td colspan="2">33</td> <td>34</td> <td colspan="2">35</td> <td rowspan="2">36</td> </tr> <tr> <td>37</td> <td>38</td> <td>39</td> <td>40</td> <td>41</td> </tr> </tbody> </table> </alternatives> </table-wrap>
验证规则
- 当单元格(td/th)带有
colspan="2"属性时,该行的有效列数需扣除1(合并2列相当于占用原本2个单元格的位置,需调整计数) - 当单元格(td/th)带有
rowspan="2"属性时,其下方相邻行的有效列数需扣除1(该单元格占用了下一行的一个位置) - 若表格存在列数不匹配(多余/缺失)、行结构异常情况,需抛出明确错误提示
实现验证的XSLT代码
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <!-- 获取表格总列数(以colgroup的col节点数量为基准) --> <xsl:variable name="total-columns" select="count(//table/colgroup/col)"/> <!-- 递归遍历所有行,验证列数完整性 --> <xsl:template match="//table"> <xsl:call-template name="row-validator"> <xsl:with-param name="target-rows" select="thead/tr | tbody/tr"/> <xsl:with-param name="prev-rowspan-count" select="0"/> </xsl:call-template> </xsl:template> <xsl:template name="row-validator"> <xsl:param name="target-rows"/> <xsl:param name="prev-rowspan-count"/> <xsl:if test="$target-rows"> <xsl:variable name="current-row" select="$target-rows[1]"/> <!-- 计算当前行有效列数:单元格总数 + colspan总和 - 单元格数 - 上一行遗留的rowspan占用数 --> <xsl:variable name="current-valid-cols" select=" count($current-row/*) + sum($current-row/*/@colspan[.='2']) - count($current-row/*) - $prev-rowspan-count "/> <!-- 列数不匹配时抛出错误并终止处理 --> <xsl:if test="$current-valid-cols != $total-columns"> <xsl:message terminate="yes"> 错误:第<xsl:value-of select="position()"/>行列数异常,预期<xsl:value-of select="$total-columns"/>列,实际有效列数为<xsl:value-of select="$current-valid-cols"/>列 </xsl:message> </xsl:if> <!-- 统计当前行遗留到下一行的rowspan数量 --> <xsl:variable name="current-rowspan-count" select="count($current-row/*/@rowspan[.='2'])"/> <!-- 递归验证下一行 --> <xsl:call-template name="row-validator"> <xsl:with-param name="target-rows" select="$target-rows[position() > 1]"/> <xsl:with-param name="prev-rowspan-count" select="$current-rowspan-count"/> </xsl:call-template> </xsl:if> </xsl:template> </xsl:stylesheet>
代码说明
- 以colgroup下的col节点数量作为表格总列数的基准值
- 通过递归遍历每一行,结合colspan的合并规则计算当前行的有效列数,再扣除上一行rowspan占用的位置
- 若有效列数与总列数不匹配,立即抛出错误并终止处理
- 记录当前行的rowspan数量,传递给下一行作为需要扣除的列数
内容的提问来源于stack exchange,提问作者BWin
相关产品推荐
相关产品推荐

