gpt4 book ai didi

Java XML 解析器添加不必要的 xmlns 和 xml :space attributes

转载 作者:太空宇宙 更新时间:2023-11-04 09:02:34 28 4
gpt4 key购买 nike

我在 Windows 10 上使用 Java 11 (AdoptOpenJDK 11.0.5 2019-10-15)。我正在解析一些旧版 XHTML 1.1 文件,这些文件采用以下一般形式:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" http://www.w3.org/MarkUp/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>XHTML 1.1 Skeleton</title>
</head>
<body>
</body>
</html>

我正在使用一个简单的非验证解析器:

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

出于某种原因,它添加了额外的属性,例如 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xml:space="preserve"到处都是:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" version="-//W3C//DTD XHTML 1.1//EN" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xml:lang="en">
<head xmlns="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<title xmlns="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">XHTML 1.1 Skeleton</title>
</head>
<body xmlns="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xml:space="preserve"></body>
</html>

我知道 DTD 可以提供默认属性值,但我不明白为什么 xmlns:xsi当该命名空间中似乎没有元素或属性时,添加了属性。

此外xml:space="preserve"似乎完全不正确;仅限类似 <pre> 的元素应该有xml:space="preserve"设定,我想。 (更新: HTML5 specification 表示 HTML 默认情况下会保留空间,并且 xml:space 不得在 HTML 中序列化,所以这可能是此处推理的一部分。我将改进我的 HTML 序列化程序以忽略 xml:space 属性,这将部分缓解此问题。)

另请注意version="-//W3C//DTD XHTML 1.1//EN"以及;这是我不需要或不想要的东西。

我做错了什么吗?有没有办法可以配置解析器不包含这些不必要的东西?

有趣的是,这对于 XHTML 1.0 严格来说不是问题。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>XHTML 1.0 Skeleton</title>
</head>
<body>
</body>
</html>

解析后会产生预期的结果:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>XHTML 1.0 Skeleton</title>
</head>
<body>
</body>
</html>

但是-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN有问题。所以这似乎只是一个 XHTML 1.1 问题。

更新:我有一些可能有用的消息:如果我创建一个没有 DTD 的新文档并将整个文档树导入到新文档中,那么所有这些麻烦(显然来自 DTD 中的隐含属性)都会消失,因为目标文档根本没有 DTD。 (参见How to force removal of attributes with implied default values from DTD in Java XML DOM。)但是这是非常低效的;解析时最好完全关闭它。

最佳答案

我找到了一个解决方法,尽管它并不理想。这个想法是,当文档要求使用 XHTML 1.1 DTD -//W3C//DTD XHTML 1.1//EN 进行解析时,真正使用 XHTML 1.0 Strict DTD -//W3C//DTD XHTML 1.0 Strict//EN 来代替。对于大多数实际用途,此 DTD 是 effectively almost the same正如他们所要求的那样,但它并没有带来所有默认的缺陷。

请记住,DefaultEntityResolver 是我的实体解析器,其中预定义了大多数 XHTML DTD(请参阅 Complete list of XHTML, MathML, and SVG modules and other entities, with public identifiers? ),其实现如下所示:

private static final EntityResolver XHTML_1_1_TO_XHTML_1_0_ENTITY_RESOLVER =
new EntityResolver() {

private final EntityResolver defaultEntityResolver = DefaultEntityResolver.getInstance();

@Override
public InputSource resolveEntity(final String publicID, final String systemID)
throws SAXException, IOException {
if(XHTML_1_1_PUBLIC_ID.equals(publicID)) {
final InputSource inputSource = resolveEntity(XHTML_1_0_STRICT_PUBLIC_ID, systemID);
inputSource.setPublicId(publicID);
return inputSource;
}
return defaultEntityResolver.resolveEntity(publicID, systemID);
}

};

然后我会在解析时使用该实体解析器:

documentBuilder.setEntityResolver(XHTML_1_1_TO_XHTML_1_0_ENTITY_RESOLVER);

这有点像拼凑,从语义上讲我不喜欢它。但对于我的应用程序,我只需要一个干净、格式良好的解析文档以及正确的实体替换,因此在实践中它可能会为大多数文档产生有效的相同结果。

关于Java XML 解析器添加不必要的 xmlns 和 xml :space attributes,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60603441/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com