如何用XSL将多个<ul>元素合并为单个<ul>包含<li>结构?
解决方案
示例输入XML
<article> <ul>第一个列表项文本</ul> <ul>第二个列表项文本</ul> <ul>第三个列表项文本</ul> <!-- 其他非<ul>节点会被原样保留 --> <p>这是文章里的一段普通文本</p> </article>
实现需求的XSLT代码
<xsl:stylesheet version="1.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> <!-- 处理article节点:合并所有子<ul> --> <xsl:template match="article"> <xsl:copy> <!-- 先保留article下非<ul>的所有子节点 --> <xsl:apply-templates select="node()[not(self::ul)]"/> <!-- 生成合并后的新<ul> --> <ul> <!-- 遍历所有原<ul>,将文本内容包装为<li> --> <xsl:for-each select="ul"> <li> <xsl:value-of select="normalize-space(.)"/> </li> </xsl:for-each> </ul> </xsl:copy> </xsl:template> <!-- 屏蔽原有的<ul>节点,避免被身份模板重复输出 --> <xsl:template match="article/ul"/> </xsl:stylesheet>
输出结果
<article> <p>这是文章里的一段普通文本</p> <ul> <li>第一个列表项文本</li> <li>第二个列表项文本</li> <li>第三个列表项文本</li> </ul> </article>
关键逻辑说明
- 身份模板确保除了
<ul>和<article>之外的所有内容(比如段落、标题等)都原样保留。 - 针对
<article>的模板专门处理合并逻辑:先输出非<ul>的内容,再统一生成一个新<ul>,把所有原<ul>的文本逐个转为<li>。 - 最后一个模板直接屏蔽原
<ul>的输出,避免重复渲染。
内容的提问来源于stack exchange,提问作者Noel Bürgler
相关产品推荐
相关产品推荐

