XSLT无法匹配带xhtml命名空间的head元素,求兼容方案
解决XSLT匹配XHTML head元素的命名空间问题
为什么匹配失败?
当HTML tidy生成带xmlns="http://www.w3.org/1999/xhtml"声明的XHTML时,所有元素(包括<head>)都属于这个XHTML命名空间。而你的XSLT模板match="//head"匹配的是无命名空间的<head>元素,自然无法命中带命名空间的目标元素。
解决方案1:针对带命名空间的XHTML匹配
在XSLT样式表中声明XHTML命名空间,然后用命名空间前缀指定匹配的元素:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xhtml="http://www.w3.org/1999/xhtml"> <!-- 匹配XHTML命名空间下的head元素 --> <xsl:template match="//xhtml:head"> <!-- 这里写入你的处理逻辑 --> <div>匹配到带命名空间的head元素</div> </xsl:template> <!-- 保留默认节点复制逻辑(可选,避免其他节点丢失) --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
解决方案2:兼容有无命名空间的XHTML
如果要让同一份样式表同时处理带/不带XHTML命名空间的文件,可以通过两种方式实现:
方式A:使用条件匹配(local-name + namespace-uri)
直接在match属性中判断元素的本地名称和命名空间:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 匹配本地名为head,且命名空间为空或为XHTML标准命名空间的元素 --> <xsl:template match="//*[local-name()='head' and (namespace-uri()='' or namespace-uri()='http://www.w3.org/1999/xhtml')]"> <!-- 统一处理逻辑 --> <div>匹配到head元素(无论是否带命名空间)</div> </xsl:template> <!-- 默认复制模板 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
方式B:分模板匹配+统一处理
写两个模板分别匹配带/不带命名空间的<head>,再调用同一个处理模板,逻辑更清晰:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xhtml="http://www.w3.org/1999/xhtml"> <!-- 匹配带XHTML命名空间的head --> <xsl:template match="//xhtml:head"> <xsl:call-template name="process-head"/> </xsl:template> <!-- 匹配无命名空间的head --> <xsl:template match="//head"> <xsl:call-template name="process-head"/> </xsl:template> <!-- 统一处理head的逻辑 --> <xsl:template name="process-head"> <div>处理head元素</div> </xsl:template> <!-- 默认复制模板 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
内容的提问来源于stack exchange,提问作者Corinna
相关产品推荐
相关产品推荐

