You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java XML解析器解析XHTML1.1时添加多余属性问题

解决AdoptOpenJDK 11解析XHTML 1.1时自动添加多余属性的问题

你遇到的这个问题,根源在于JDK 11默认使用的Xerces解析器——哪怕你开启了非验证模式,它仍会加载XHTML 1.1的DTD并自动注入一些额外属性。这些多余的xmlns:xsi、xml:space="preserve"和version属性,都是解析器处理DTD时的“过度行为”;尤其是XHTML 1.1的DTD结构比XHTML 1.0 Strict更复杂,若关联MathML/SVG模块,还会让解析器混淆DTD与XML Schema的处理逻辑。

不用事后导入新文档,你可以通过配置DocumentBuilderFactory的关键特性,直接在解析阶段阻止这些属性生成:

解决方案:配置解析器特性

修改你的DocumentBuilderFactory初始化代码,添加以下特性设置:

DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);

// 核心设置:关闭外部DTD的加载与语法处理
documentBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
documentBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);

// 可选:明确关闭XML Schema相关自动处理,避免注入xsi命名空间
documentBuilderFactory.setFeature("http://apache.org/xml/features/validation/schema", false);

// 可选:禁用xml:space属性的自动添加
documentBuilderFactory.setFeature("http://apache.org/xml/features/dom/xml-space/preserve", false);

DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
final Document document;
try (InputStream inputStream = new BufferedInputStream(getClass().getResourceAsStream("xhtml-1.1-test.xhtml"))) {
    document = documentBuilder.parse(inputStream);
}

为什么这些设置有效?

  • load-dtd-grammar和load-external-dtd设为false后,解析器会完全跳过XHTML 1.1 DTD的加载,既不会读取DTD中的默认属性定义,也不会因解析逻辑错误注入额外属性。
  • 关闭validation/schema特性,能避免解析器误将XHTML 1.1的DTD处理逻辑与XML Schema的xsi命名空间关联,从而阻止xmlns:xsi的自动添加。
  • xml-space/preserve设为false,会关闭解析器自动给元素添加xml:space="preserve"的行为——这个属性本来就只应在<pre>等需要保留空格的元素上手动设置。

这个方案对纯XHTML 1.1以及包含MathML 2.0、SVG 1.1的混合文档都有效,且是在解析阶段直接处理,比事后导入新文档的效率高很多。

内容的提问来源于stack exchange,提问作者Garret Wilson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 20:37:46