能否无需修改HTML文件,用xsl:copy-of加载含未声明实体的外部文件?
问题背景
我有一个无法修改的HTML文件,里面包含拉丁字符实体(比如á),内容如下:
<root> <h1> Actividades acuáticas </h1> <p> Actividades acuáticas </p> </root>
我尝试用以下XSLT代码加载该文件的节点:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="html"/> <xsl:template match="/"> <xsl:copy-of select="document('content.html')/root/p/node()"/> </xsl:template> </xsl:stylesheet>
运行时报错:
The entity "aacute" was referenced, but not declared.
只有给HTML文件添加DOCTYPE声明后才能正常运行,修改后的内容如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <root> <h1> Actividades acuáticas </h1> <p> Actividades acuáticas </p> </root>
请问有没有无需修改该HTML文件的解决方法?
解决方案
有几种不需要修改原HTML文件的可行方案:
1. 在XSLT内部声明所需实体
直接在XSLT的样式表中添加实体定义,覆盖解析时的实体缺失问题,适合用到的实体数量不多的场景:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <!DOCTYPE xsl:stylesheet [ <!ENTITY aacute "á"> <!-- 若有其他拉丁实体,可在此继续添加声明 --> ]> <xsl:output method="html"/> <xsl:template match="/"> <xsl:copy-of select="document('content.html')/root/p/node()"/> </xsl:template> </xsl:stylesheet>
2. 配置XML解析器的实体处理规则
如果使用的XSLT处理器支持自定义解析配置,可以开启解析器的“自动识别HTML实体”或“忽略未声明实体”选项。比如在Java环境中,可通过DocumentBuilderFactory设置相关参数,让解析器自动加载HTML标准实体定义,无需修改原文件。
3. 以文本形式读取并替换实体(依赖扩展)
借助EXSLT这类扩展函数,先把HTML文件当作纯文本读取,将实体替换为对应Unicode字符后再解析为XML节点:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:str="http://exslt.org/strings" version="1.0" extension-element-prefixes="str"> <xsl:output method="html"/> <xsl:template match="/"> <!-- 读取原文件为文本内容 --> <xsl:variable name="raw-text" select="document('content.html')"/> <!-- 替换目标实体为Unicode字符 --> <xsl:variable name="fixed-text" select="str:replace($raw-text, '&aacute;', 'á')"/> <!-- 解析处理后的文本并提取目标节点 --> <xsl:copy-of select="str:parse($fixed-text)/root/p/node()"/> </xsl:template> </xsl:stylesheet>
注:该方案需要XSLT处理器支持EXSLT扩展。
4. 用HTML解析器预处理文件
先用第三方HTML解析工具(如Python的BeautifulSoup、Java的Jsoup)把原HTML文件转换为合法的XHTML格式,再用XSLT处理转换后的文件。整个过程不需要修改原文件,仅做一次中间预处理。
内容的提问来源于stack exchange,提问作者PoseLab
相关产品推荐
相关产品推荐

