如何根据vmerge节点为entry元素添加@morerows属性?
解决方案
核心处理规则
针对OOXML表格转结构化表格的垂直合并属性匹配需求,处理逻辑如下:
- 遍历表格所有
<tr>节点,按列定位垂直合并起始标记:当单元格<tc>的属性节点<tcPr>下存在<vmerge val="restart"/>时,启动合并计数 - 从当前行的下一行开始,逐行校验同列位置的
<tc>是否包含无属性的<vmerge/>标记,每匹配到一个计数加1,直到同列单元格无<vmerge/>标记时停止计数 - 最终计数值即为起始单元格对应
<entry>的@morerows属性值,合并组内后续带空<vmerge/>的单元格对应的<entry不需要保留内容,也无需添加@morerows属性
实现示例(XSLT 2.0版本,适合XML结构化转换场景)
<xsl:template match="tc[tcPr/vmerge/@val='restart']"> <xsl:variable name="currentColPos" select="count(preceding-sibling::tc) + 1"/> <xsl:variable name="currentRowPos" select="count(../preceding-sibling::tr) + 1"/> <!-- 统计后续同列的vmerge数量 --> <xsl:variable name="mergeCount" select="count(../../tr[position() > $currentRowPos]/tc[count(preceding-sibling::tc) + 1 = $currentColPos][tcPr/vmerge[not(@val)]])"/> <entry align="left" morerows="{$mergeCount}"> <xsl:apply-templates select="*[not(self::tcPr)]"/> </entry> </xsl:template> <!-- 匹配合并组内的空vmerge单元格 --> <xsl:template match="tc[tcPr/vmerge[not(@val)]]"> <entry align="left"> <p></p> </entry> </xsl:template>
按照你给出的输入示例,第二列的垂直合并起始单元格后续匹配到1个带空<vmerge/>的单元格,最终输出的对应<entry>应为<entry morerows="1" align="left">,你提供的预期输出中morerows为空属于占位内容,可按实际计数填充。
Python实现示例(基于lxml库)
from lxml import etree def add_morerows(tbl_xml): root = etree.fromstring(tbl_xml) trs = root.xpath('.//tr') col_count = len(root.xpath('.//gridCol')) for row_idx, tr in enumerate(trs): tcs = tr.xpath('./tc') for col_idx, tc in enumerate(tcs): # 检查是否是合并起始 if tc.xpath('./tcPr/vmerge[@val="restart"]'): merge_cnt = 0 # 遍历后续行同列 for next_row in trs[row_idx+1:]: next_tc = next_row.xpath(f'./tc[{col_idx+1}]') if next_tc and next_tc[0].xpath('./tcPr/vmerge[not(@val)]'): merge_cnt +=1 else: break # 生成entry的时候带上morerows # 此处可补充完整的节点转换逻辑 print(f"对应entry的morerows值为: {merge_cnt}")
内容的提问来源于stack exchange,提问作者Kita Ansari
相关产品推荐
相关产品推荐

