【问题标题】:Fatal Error :1:40: Content is not allowed in prolog致命错误:1:40:序言中不允许内容
【发布时间】:2016-03-17 20:19:28
【问题描述】:

我有一个用 UTF-16 LE 编码的超级简单的 XML 文档。

<?xml version="1.0" encoding="utf-16"?><X id="1" />

我正在加载它(使用jcabi-xml):

BOMInputStream bomIn = new BOMInputStream(Main.class.getResourceAsStream("resources/test.xml"), ByteOrderMark.UTF_16LE);
String firstNonBomCharacter = Character.toString((char)bomIn.read());
Reader reader = new InputStreamReader(bomIn, "UTF-16");
String xmlString = IOUtils.toString(reader);
xmlString = xmlString.trim();
xmlString = firstNonBomCharacter + xmlString;
bomIn.close();
reader.close();
final XML xml = new XMLDocument(xmlString);

我已通过保存文件并使用十六进制编辑器检查它来检查是否没有额外的 BOM/垃圾符号(前导或任何位置)。 XML 格式正确。

但是,我仍然收到以下错误:

[Fatal Error] :1:40: Content is not allowed in prolog.
Exception in thread "main" java.lang.IllegalArgumentException: Invalid XML: "<?xml version="1.0" encoding="utf-16"?><X id="1" />"
    at com.jcabi.xml.DomParser.document(DomParser.java:115)
    at com.jcabi.xml.XMLDocument.<init>(XMLDocument.java:155)
    at Main.getTransformedString(Main.java:47)
    at Main.main(Main.java:26)
Caused by: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 40; Content is not allowed in prolog.
    at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source)
    at javax.xml.parsers.DocumentBuilder.parse(Unknown Source)
    at com.jcabi.xml.DomParser.document(DomParser.java:105)
    ... 3 more

我已经在谷歌上搜索了这个错误,但他们都说这是 BOM 的错,我已经确认(据我所知)并非如此。还有什么问题?

【问题讨论】:

  • 如果文件是 UTF-16 格式,那么 BOM 不应该保留文件的前两个字节吗?如果你添加另一个bomIn.read(); 来丢弃第二个字节怎么办?
  • 实际上,既然我已经查看了 BOMInputStream 的 JavaDocs,您应该完全删除 bomIn.read() 调用,因为流会为您丢弃 BOM。
  • @MickMnemonic 我也是这么想的,但是当我不打电话给bomIn.read() 时,我的字符串变成了由问号组成的东西。老实说,我不太确定如何使用 BOMInputStream,但这个答案 (stackoverflow.com/questions/1835430/…) 写道,调用 read 会跳到第一个非 bom 字符(我忘记包含在我的示例代码中)。跨度>
  • 如果您正在使用 BOM,则应告知 InputStreamReader 字节序:Reader reader = new InputStreamReader(bomIn, StandardCharsets.UTF_16LE);
  • @MickMnemonic 现在无需致电bomIn.read() 即可完成工作,谢谢!然而,实际错误本身仍然存在。

标签: java xml xml-parsing


【解决方案1】:

以下对我有用:

    try (InputStream stream = Test.class.getResourceAsStream("/Test.xml")) {
        StreamSource source = new StreamSource(stream);
        final XML xml = new XMLDocument(source);
    }

使用输入文件的十六进制转储:

FF FE 3C 00 3F 00 78 00 6D 00 6C 00 20 00 76 00 65 00 72 00 73 00 69 00  
6F 00 6E 00 3D 00 27 00 31 00 2E 00 30 00 27 00 20 00 65 00 6E 00 63 00 
6F 00 64 00 69 00 6E 00 67 00 3D 00 27 00 55 00 54 00 46 00 2D 00 31 00 
36 00 27 00 3F 00 3E 00 3C 00 58 00 20 00 69 00 64 00 3D 00 22 00 31 00 
22 00 2F 00 3E 00

据我所知,在您的示例中,您将文件的内容转换为字符串。但这是有问题的,因为当您将字节转换为字符串时,您实际上丢弃了编码。当 SAX 解析器将字符串转换为字节数组时,它决定它将是 UTF-8,但序言指出它是 UTF-16,所以你遇到了问题。

相反,当我使用 StreamSource 时,它​​只是自动检测到文件是从 BOM 中以 UTF-16 LE 编码的事实。

如果您没有使用 java-7 或更高版本并且无法使用 try-with-resources,请像以前一样使用 stream.close()。

【讨论】:

    猜你喜欢
    • 2012-07-19
    • 1970-01-01
    • 2015-01-30
    • 1970-01-01
    • 1970-01-01
    • 2021-05-09
    • 2020-03-26
    • 2022-10-13
    • 2023-04-10
    相关资源
    最近更新 更多