使用XSLT复制HTML <meta>标签失败问题求助
解决XML中嵌入非规范HTML导致的XSLT解析错误
你遇到的问题本质是XML的严格语法要求和HTML的松散语法不兼容——XML强制所有元素必须有匹配的结束标签,而传统HTML里像<META>这类标签经常省略闭合标签,这就触发了XML解析器的报错。下面给你几个可行的解决方案:
方案1:把HTML转为合法的XHTML(最稳妥)
先将嵌入的HTML转换成符合XML规范的XHTML,这样XML解析器就能正常处理了。你可以用专门的工具来做这件事,比如HTML Tidy:
tidy -asxhtml -output cleaned_xhtml.html your_original.html
这个命令会把你的HTML自动修正为带闭合标签的XHTML,比如把<META>改成<META/>或者补全</META>。之后把修正后的XHTML内容放回XML文件里,再用XSLT提取就不会报错了。
如果不想用工具,也可以手动修正那些不闭合的标签,比如:
<!-- 修正前的HTML --> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8"> <!-- 修正后的XHTML --> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8"/>
方案2:用CDATA段包裹HTML内容
如果没法提前修正HTML,那可以在XML里把HTML内容放在<![CDATA[...]]>这个CDATA段里——XML解析器会把CDATA里的内容当作纯文本,不会检查标签的闭合性。
比如修改你的XML结构:
<embedded-html> <![CDATA[ <HTML> <HEAD> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8"> <!-- 其他HTML内容 --> </HEAD> <BODY> <!-- 页面内容 --> </BODY> </HTML> ]]> </embedded-html>
然后在XSLT里提取内容时,记得加上disable-output-escaping="yes",这样输出的HTML标签不会被转义:
<xsl:template match="/"> <xsl:value-of select="embedded-html" disable-output-escaping="yes"/> </xsl:template>
方案3:使用支持HTML解析的XSLT扩展函数
如果你的XSLT处理器支持扩展(比如Saxon-PE/EE),可以用parse-html()函数直接解析非规范的HTML,不需要提前修正。比如在XSLT 2.0及以上版本中:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions"> <xsl:template match="/"> <!-- 提取XML中的HTML文本并解析为文档节点 --> <xsl:variable name="html-document" select="fn:parse-html(//embedded-html/text())"/> <!-- 现在可以像操作XML一样提取HTML里的内容,比如获取所有meta标签 --> <xsl:copy-of select="$html-document//head/meta"/> </xsl:template> </xsl:stylesheet>
这个方法的好处是不需要修改原始XML或HTML,直接在XSLT里处理,但要注意你的处理器是否支持这个函数。
内容的提问来源于stack exchange,提问作者zanza67
相关产品推荐
相关产品推荐

