XSL 2.0中xsl:for-each-group处理OpenXML转XML嵌套分组不生效问题
问题原因
当前代码仅实现了TRSubtitle1层级的一级分组,没有对组内的TRSubtitle2二级标题做二次嵌套分组,因此二级章节内容只能平铺在一级<section>下,无法生成嵌套结构。
修正后完整XSL代码
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:pkg="http://schemas.microsoft.com/office/2006/xmlPackage" xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex" xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex" xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex" xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" xmlns:random="java:java.util.Random" xmlns:mf="http://example.com/mf" exclude-result-prefixes="#all" version="2.0"> <xsl:output indent="yes" method="xml" encoding="UTF-8"/> <xsl:strip-space elements="*"/> <xsl:template match="pkg:part[not(descendant::w:document)]"/> <!-- 移除超链接标记,避免脚注编号异常 --> <xsl:template match="w:hyperlink"/> <!-- 普通段落转换模板 --> <xsl:template match="w:p[not(w:pPr/w:pStyle/@w:val=('TRH1','TRSubtitle1','TRSubtitle2'))]"> <para num="{count(preceding-sibling::w:p[not(w:pPr/w:pStyle[@w:val='TRH1' or @w:val='TRSubtitle1' or @w:val='TRSubtitle2'])])+1}"> <xsl:apply-templates/> </para> </xsl:template> <!-- 章节标题转换模板 --> <xsl:template match="w:p[w:pPr/w:pStyle/@w:val=('TRSubtitle1','TRSubtitle2')]"> <stitle> <xsl:apply-templates/> </stitle> </xsl:template> <!-- 非段落节点(表格等)复制模板 --> <xsl:template match="*[not(self::w:p)]"> <xsl:copy copy-namespaces="no"> <xsl:apply-templates/> </xsl:copy> </xsl:template> <xsl:template match="w:body"> <chapter-poc> <ctitle>XXX XXX</ctitle> <!-- 一级分组:匹配TRSubtitle1开头的章节 --> <xsl:for-each-group select="*[normalize-space()]" group-starting-with="w:p[w:pPr/w:pStyle[@w:val='TRSubtitle1']]"> <xsl:choose> <xsl:when test="current-group()[self::w:p[w:pPr/w:pStyle[@w:val='TRH1']]]"> <sub-chapter> <sctitle> <xsl:apply-templates/> </sctitle> </sub-chapter> </xsl:when> <xsl:otherwise> <section> <!-- 二级分组:匹配当前一级分组内TRSubtitle2开头的子章节 --> <xsl:for-each-group select="current-group()" group-starting-with="w:p[w:pPr/w:pStyle/@w:val='TRSubtitle2']"> <xsl:choose> <!-- 二级章节内容包裹为内层section --> <xsl:when test="self::w:p[w:pPr/w:pStyle/@w:val='TRSubtitle2']"> <section> <xsl:apply-templates select="current-group()"/> </section> </xsl:when> <!-- 一级章节下的直接内容直接输出 --> <xsl:otherwise> <xsl:apply-templates select="current-group()"/> </xsl:otherwise> </xsl:choose> </xsl:for-each-group> </section> </xsl:otherwise> </xsl:choose> </xsl:for-each-group> </chapter-poc> </xsl:template> </xsl:stylesheet>
适配说明
代码核心改动是在一级<section>生成逻辑中,新增了针对TRSubtitle2的二级分组逻辑,将二级标题及其后续内容自动包裹为内层<section>节点,同时将不同类型节点的转换逻辑抽为独立模板,结构更清晰。使用该代码转换示例XML,输出结果与期望输出完全一致。
内容的提问来源于stack exchange,提问作者Amrendra Kumar
相关产品推荐
相关产品推荐

