如何编写XSLT提取并转换指定XHTML内容?
XSLT解决方案:提取指定XHTML子集并完成转换
以下是满足需求的XSLT方案,实现提取id为key_div的<div>内<h2>及后续内容、转换<h2>为<h1>、修改列表内<a>的href属性:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xhtml="http://www.w3.org/1999/xhtml" exclude-result-prefixes="xhtml"> <!-- 身份转换模板:默认复制所有节点和属性 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 匹配根节点,定位到目标div并处理其内容 --> <xsl:template match="/"> <xsl:apply-templates select="//xhtml:div[@id='key_div']/xhtml:h2"/> <xsl:apply-templates select="//xhtml:div[@id='key_div']/xhtml:h2/following-sibling::node()"/> </xsl:template> <!-- 将<h2>转换为<h1>,保留原属性和子内容 --> <xsl:template match="xhtml:h2"> <h1> <xsl:apply-templates select="@*|node()"/> </h1> </xsl:template> <!-- 修改列表内<a>的href属性(示例:给href添加前缀) --> <xsl:template match="xhtml:ul//xhtml:a/@href | xhtml:ol//xhtml:a/@href"> <xsl:attribute name="href"> <!-- 这里替换为你的href修改逻辑,示例是添加前缀 --> <xsl:text>/new-base-path/</xsl:text> <xsl:value-of select="."/> </xsl:attribute> </xsl:template> <!-- 忽略目标div外的所有内容,以及目标div内<h2>之前的内容 --> <xsl:template match="*[not(ancestor-or-self::xhtml:div[@id='key_div'])] | xhtml:div[@id='key_div']/*[not(self::xhtml:h2) and not(preceding-sibling::xhtml:h2)]"/> </xsl:stylesheet>
关键部分说明:
- 命名空间处理:如果你的XHTML文档带有
http://www.w3.org/1999/xhtml命名空间,必须在XSLT中声明并使用前缀匹配节点;如果没有命名空间,可删除所有xhtml:前缀和命名空间声明。 - 内容提取逻辑:先处理
<h2>节点,再选取其之后的所有兄弟节点,确保输出顺序和原文档一致。 转
:专门匹配<h2>节点,输出<h1>并保留原节点的属性和子内容,不丢失任何原有信息。- href修改:针对
<ul>和<ol>下的所有<a>标签的href属性,自定义修改逻辑(示例为添加前缀,你可以替换为字符串替换、路径重写等逻辑)。 - 冗余内容过滤:最后一个模板会忽略目标div之外的所有内容,以及目标div内
<h2>之前的内容,确保只输出需要的子集。
调整建议:
- 如果需要修改
href的逻辑不同(比如替换特定字符串),XSLT 2.0及以上可使用replace(., '旧前缀', '新前缀');若用XSLT 1.0,可结合concat和substring实现类似效果。 - 若目标
<h2>是目标div的第一个子节点,可简化内容提取的模板逻辑。
内容的提问来源于stack exchange,提问作者HangarRash
相关产品推荐
相关产品推荐

