Фатальная ошибка: 1: 40: содержание не допускается в прологе
У меня есть супер простой XML-документ, закодированный в файле UTF-16.
<?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/junk (ведущих или где-либо еще), сохранив файл и проверив его с помощью шестнадцатеричного редактора. 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, которую я подтвердил (to насколько мне известно, это не так. Что еще может быть не так?
1 ответ:
Для меня работает следующее:
try (InputStream stream = Test.class.getResourceAsStream("/Test.xml")) { StreamSource source = new StreamSource(stream); final XML xml = new XMLDocument(source); }С шестнадцатеричным дампом входного файла:
Насколько я могу судить, в вашем примере вы конвертируете содержимое файла в строку. Но это проблематично, потому что вы фактически отбрасываете кодировку, когда преобразуете байты в строку. Когда синтаксический анализатор SAX преобразует строку в массив байтов, он решает, что это будет UTF-8, но пролог утверждает, что это UTF-16, и поэтому у вас есть проблема.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Вместо этого, когда я использую StreamSource, он просто автоматически обнаруживает тот факт, что файл закодирован в файле UTF-16 из спецификации.
Если вы не используете java-7 или up и не можете использовать try-with-resources, то используйте поток.close() как и раньше.
Comments