使用XSLT合并同属性值相邻标签并保留子标签
合并相邻相同href的标签并保留子元素的XSLT方案
核心实现思路
利用XSLT 2.0的for-each-group指令,对相邻的<a>标签按@href属性值分组,每组生成一个新的<a>标签,保留原href属性,并将组内所有<a>标签的子节点(包括<em>、<code>等)全部移入新标签中,非<a>标签节点则直接保留原有结构。
完整XSLT代码
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 默认复制模板:保留所有节点与属性的原始结构 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 处理包含<a>标签的父节点,执行相邻分组逻辑 --> <xsl:template match="*[a]"> <xsl:copy> <xsl:apply-templates select="@*"/> <xsl:for-each-group select="node()" group-adjacent="boolean(self::a) and @href"> <!-- 处理同href的相邻<a>标签组 --> <xsl:if test="current-grouping-key()"> <a href="{current-group()[1]/@href}"> <xsl:apply-templates select="current-group()/node()"/> </a> </xsl:if> <!-- 处理非<a>标签的节点组,直接复制 --> <xsl:if test="not(current-grouping-key())"> <xsl:apply-templates select="current-group()"/> </xsl:if> </xsl:for-each-group> </xsl:copy> </xsl:template> </xsl:stylesheet>
关键逻辑说明
- 默认复制模板:保证文档中未涉及
<a>标签的部分完全保留原有结构,不会被修改。 - 分组规则:
group-adjacent="boolean(self::a) and @href"确保只有相邻且href相同的<a>标签会被归为一组,非<a>标签或href不同的<a>标签会单独处理。 - 子节点保留:通过
current-group()/node()将组内所有<a>标签的子节点完整导入新生成的<a>标签中,不会丢失<em>、<code>等嵌套元素。
示例效果
输入XHTML片段
<p> 请查看<a href="/guides"><em>入门指南</em></a><a href="/guides"><code>进阶教程</code></a>,以及<a href="/faq">常见问题</a> </p>
转换后输出
<p> 请查看<a href="/guides"><em>入门指南</em><code>进阶教程</code></a>,以及<a href="/faq">常见问题</a> </p>
内容的提问来源于stack exchange,提问作者Greg
相关产品推荐
相关产品推荐

