如何用XSLT 2.0重构Student_Response相关XML节点?求助
解决方案
问题核心是未正确对连续的Student_Response和Student_Response_Italic节点分组,导致重复匹配嵌套。用XSLT 2.0的分组功能可以解决这个问题,以下是具体实现:
示例源XML
<Root> <Student_Response>普通文本1</Student_Response> <Student_Response_Italic>斜体文本1</Student_Response_Italic> <Student_Response>普通文本2</Student_Response> <Student_Response>普通文本3</Student_Response> <Student_Response_Italic>斜体文本2</Student_Response_Italic> <!-- 其他非目标节点示例 --> <Other_Node>保留内容</Other_Node> </Root>
期望输出HTML
<Root> <Student_Response>普通文本1<i>(斜体文本1)</i>普通文本2普通文本3<i>(斜体文本2)</i></Student_Response> <Other_Node>保留内容</Other_Node> </Root>
修正后的XSLT 2.0代码
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" indent="yes"/> <!-- 处理根节点,对目标节点分组 --> <xsl:template match="Root"> <Root> <!-- 将连续的Student_Response/Student_Response_Italic归为一组 --> <xsl:for-each-group select="*" group-adjacent="self::Student_Response or self::Student_Response_Italic"> <xsl:choose> <!-- 处理目标节点组 --> <xsl:when test="current-grouping-key()"> <Student_Response> <xsl:apply-templates select="current-group()"/> </Student_Response> </xsl:when> <!-- 非目标节点直接复制 --> <xsl:otherwise> <xsl:apply-templates select="current-group()"/> </xsl:otherwise> </xsl:choose> </xsl:for-each-group> </Root> </xsl:template> <!-- 普通响应节点直接输出文本 --> <xsl:template match="Student_Response"> <xsl:value-of select="."/> </xsl:template> <!-- 斜体响应节点用<i>包裹并添加括号 --> <xsl:template match="Student_Response_Italic"> <i>(<xsl:value-of select="."/>)</i> </xsl:template> <!-- 默认模板:复制其他节点和属性 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
关键说明
- 用
group-adjacent把连续的目标节点归为一组,避免跨组重复处理,从根源解决嵌套问题。 - 分组后统一生成单个
Student_Response节点,再分别处理组内的普通和斜体内容。 - 默认模板保留非目标节点的原有结构,不影响XML其他部分的转换。
内容的提问来源于stack exchange,提问作者Randy H in CT
相关产品推荐
相关产品推荐

