XSLT3中相邻节点分组与混合内容处理问题求助
解决方案:合并含右大括号的相邻
段落并修复XSLT3问题
针对你遇到的两个问题,以下是具体修复方案和XSLT3代码实现:
问题根源分析
- 未处理右大括号后的混合内容:原代码仅关注右大括号及之前的文本,未提取并追加每个段落中右大括号后的节点(包括文本和嵌套元素)。
- 缺失部分
段落:原分组逻辑可能只处理了含右大括号的段落,忽略了不包含右大括号的独立
,导致TOKEN6、TOKEN12这类段落丢失。
修复后的XSLT3代码
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 默认复制所有未匹配的节点 --> <xsl:mode on-no-match="shallow-copy"/> <!-- 处理包含<p>的父节点(示例为<body>,可根据实际结构调整) --> <xsl:template match="body"> <xsl:copy> <!-- 按是否包含右大括号分组相邻<p> --> <xsl:for-each-group select="p" group-adjacent="contains(., '}')"> <!-- 处理包含右大括号的相邻段落组 --> <xsl:if test="current-grouping-key()"> <p> <!-- 合并每个段落中右大括号及之前的内容 --> <xsl:for-each select="current-group()"> <xsl:analyze-string select="." regex="(.*\})"> <xsl:matching-substring> <xsl:value-of select="regex-group(1)"/> </xsl:matching-substring> </xsl:analyze-string> </xsl:for-each> <!-- 追加所有段落中右大括号后的混合内容(支持嵌套元素) --> <xsl:for-each select="current-group()"> <xsl:analyze-string select="." regex=".*\}(.*)"> <xsl:matching-substring> <xsl:copy-of select="regex-group(1)"/> </xsl:matching-substring> </xsl:analyze-string> </xsl:for-each> </p> </xsl:if> <!-- 直接输出不包含右大括号的独立段落,避免丢失 --> <xsl:if test="not(current-grouping-key())"> <xsl:copy-of select="current-group()"/> </xsl:if> </xsl:for-each-group> </xsl:copy> </xsl:template> </xsl:stylesheet>
关键逻辑说明
- 分组规则:使用
group-adjacent="contains(., '}')"将相邻的含右大括号的归为一组,不含右大括号的
单独成组,确保这类段落不会被丢弃。
- 合并右大括号前内容:通过
xsl:analyze-string精准提取每个中右大括号及之前的内容,合并到新的
节点中。
- 追加右大括号后内容:同样用
xsl:analyze-string提取每个中右大括号后的所有节点(包括文本和嵌套元素),追加到合并后的
末尾,解决混合内容未处理的问题。
扩展说明
如果XML中
内存在多个右大括号(如{a}{b}),可调整正则表达式为(.*?\})实现逐个提取;若需要保留右大括号后的节点结构(而非仅文本),xsl:copy-of会完整复制所有嵌套元素,确保输出结构与原内容一致。
内容的提问来源于stack exchange,提问作者Tench
相关产品推荐
相关产品推荐

