publicId 和 systemId 之间需要空格,但 XML 看起来没问题

use*_*408 3 jaxb xml-parsing

我刚刚拿出几个月前写的一段代码。该代码从 Web 服务器获取 XML 文档并使用 JAXB 对其进行解析。上次我尝试时,效果非常好;现在我遇到了一个例外:

\n\n
org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 50; White spaces are required between publicId and systemId.\n    at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:257)\n    at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:339)\n    at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:121)\n
Run Code Online (Sandbox Code Playgroud)\n\n

环顾四周,这表明 XML 标头数据存在一些问题,即<!DOCTYPE ...>. 答案表明该声明具有误导性:在所描述的情况下,systemId 完全丢失,尽管错误只是抱怨其前面缺少空格。

\n\n

但是,如果我使用 Web 浏览器获取 XML 文档,它甚至不包含标<!DOCTYPE ...>头。

\n\n

解析我几个月前检索到的 XML 文档没有出现任何问题。

\n\n

如果我比较今天检索到的文档和几个月前的文档,则两者在根元素的开头都是完全相同的。

\n

use*_*408 11

捕获 HTTP 流量最终提供了答案(未加密的连接有时会派上用场):显然,该服务在过去几个月从 HTTP 切换到了 HTTPS,而 URL 则保持不变。

\n\n

对旧 URL 的请求将得到301 Moved Permanently新 URL 的响应。

\n\n

从带有 的 URL 读取时java.net.URL.openStream(),不会自动遵循重定向。因此,它返回的数据不是有效的 XML,从而导致错误消息。

\n\n

今天的经验教训:publicId 和 systemId 之间需要空格实际上只是一种神秘的说法:您提供的 XML 数据有一些\xe2\x80\x99s 错误,但我们没有\xe2\x80\x99t 费心去挖掘任何内容更深。

\n