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
相关产品推荐
相关产品推荐

