Фатальная ошибка: 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 насколько мне известно, это не так. Что еще может быть не так?

699   1  

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, он просто автоматически обнаруживает тот факт, что файл закодирован в файле UTF-16 из спецификации.

Если вы не используете java-7 или up и не можете использовать try-with-resources, то используйте поток.close() как и раньше.

Comments

    Ничего не найдено.