"Содержимое недопустимо в прологе" при разборе совершенно корректного XML на GAE
Последние 48 часов я бьюсь головой об этой абсолютно бешеной клопе, поэтому решил, что наконец-то добавлю полотенце и попробую спросить здесь, прежде чем выбросить свой ноутбук в окно.
Я пытаюсь проанализировать XML-ответ от звонка, который я сделал в AWS SimpleDB. Ответ возвращается по проводам просто отлично; например, это может выглядеть так:
<?xml version="1.0" encoding="utf-8"?>
<ListDomainsResponse xmlns="http://sdb.amazonaws.com/doc/2009-04-15/">
<ListDomainsResult>
<DomainName>Audio</DomainName>
<DomainName>Course</DomainName>
<DomainName>DocumentContents</DomainName>
<DomainName>LectureSet</DomainName>
<DomainName>MetaData</DomainName>
<DomainName>Professors</DomainName>
<DomainName>Tag</DomainName>
</ListDomainsResult>
<ResponseMetadata>
<RequestId>42330b4a-e134-6aec-e62a-5869ac2b4575</RequestId>
<BoxUsage>0.0000071759</BoxUsage>
</ResponseMetadata>
</ListDomainsResponse>
Я передаю этот XML парсеру с
XMLEventReader eventReader = xmlInputFactory.createXMLEventReader(response.getContent());
и позвонить eventReader.nextEvent();
кучу раз, чтобы получить данные, которые я хочу.
Вот странная часть - она прекрасно работает на локальном сервере. Ответ приходит, я его разбираю, все довольны. Проблема заключается в том, что при развертывании кода в Google App Engine исходящий запрос все еще работает, и XML-ответ мне кажется на 100% идентичным и правильным, но ответ не удается проанализировать со следующим исключением:
com.amazonaws.http.HttpClient handleResponse: Unable to unmarshall response (ParseError at [row,col]:[1,1]
Message: Content is not allowed in prolog.): <?xml version="1.0" encoding="utf-8"?>
<ListDomainsResponse xmlns="http://sdb.amazonaws.com/doc/2009-04-15/"><ListDomainsResult><DomainName>Audio</DomainName><DomainName>Course</DomainName><DomainName>DocumentContents</DomainName><DomainName>LectureSet</DomainName><DomainName>MetaData</DomainName><DomainName>Professors</DomainName><DomainName>Tag</DomainName></ListDomainsResult><ResponseMetadata><RequestId>42330b4a-e134-6aec-e62a-5869ac2b4575</RequestId><BoxUsage>0.0000071759</BoxUsage></ResponseMetadata></ListDomainsResponse>
javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,1]
Message: Content is not allowed in prolog.
at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(Unknown Source)
at com.sun.xml.internal.stream.XMLEventReaderImpl.nextEvent(Unknown Source)
at com.amazonaws.transform.StaxUnmarshallerContext.nextEvent(StaxUnmarshallerContext.java:153)
... (rest of lines omitted)
Я дважды, трижды, четверно проверял этот XML на наличие "невидимых символов" или символов, не кодированных в UTF8, и т. Д. Я просматривал его побайтово в массиве для меток порядка следования байтов или чего-то в этом роде. Ничего такого; он проходит каждый проверочный тест, который я мог бы выполнить. Еще более странно, что это происходит, если я использую синтаксический анализатор на основе Saxon, но ТОЛЬКО в GAE он всегда отлично работает в моей локальной среде.
Это очень трудно отследить код для проблем, когда я могу запустить отладчик только в среде, которая отлично работает (я не нашел хорошего способа удаленной отладки в GAE). Тем не менее, используя мои примитивные средства, я попробовал миллион подходов, в том числе:
- XML с прологом и без
- С и без перевода строки
- С и без атрибута "encoding=" в прологе
- Оба стиля новой строки
- С информацией о порции и без нее, присутствующей в потоке HTTP
И я попробовал большинство из них в нескольких комбинациях, где имело смысл, что они будут взаимодействовать - ничего! Я в конце своего остроумия. Кто-нибудь видел подобную проблему до этого, можно надеяться, пролить свет на это?
Спасибо!
17 ответов
Кодировка в вашем XML и XSD (или DTD) различна.
Заголовок файла XML: <?xml version='1.0' encoding='utf-8'?>
Заголовок файла XSD: <?xml version='1.0' encoding='utf-16'?>
Другой возможный сценарий, который вызывает это, когда что-либо предшествует объявлению типа документа XML. то есть у вас может быть что-то вроде этого в буфере:
helloworld<?xml version="1.0" encoding="utf-8"?>
или даже пробел или специальный символ.
Есть некоторые специальные символы, называемые маркерами порядка байтов, которые могут быть в буфере. Перед передачей буфера в Parser сделайте это...
String xml = "<?xml ...";
xml = xml.trim().replaceFirst("^([\\W]+)<","<");
У меня возникли проблемы при проверке XML-файла в Notepad++ и сохранении файла, хотя у меня был верхний XML-тег utf-8 как <?xml version="1.0" encoding="utf-8"?>
Исправлено сохранением файла в notpad++ с помощью Encoding(Tab) > Encode in UTF-8: выбран (был Encode в UTF-8-BOM)
Это сообщение об ошибке всегда вызывается недопустимым содержимым XML в начальном элементе. Например, дополнительная маленькая точка "." В начале элемента XML.
Любые символы перед " <?xml….
" Вызовет выше" org.xml.sax.SAXParseException: содержимое не разрешено в прологе "сообщение об ошибке.
Маленькая точка " . " перед “<?xml….
Чтобы это исправить, просто удалите все эти странные символы перед “<?xml“
,
Ссылка: http://www.mkyong.com/java/sax-error-content-is-not-allowed-in-prolog/
Сегодня я поймал такое же сообщение об ошибке. Решением было изменить документ с UTF-8 с BOM на UTF-8 без BOM.
Я столкнулся с той же проблемой. В моем случае XML-файлы были сгенерированы из программы на C# и переданы в AS400 для дальнейшей обработки. После некоторого анализа выяснилось, что я использовал кодировку UTF8 при создании файлов XML, тогда как javac(в AS400) использует "UTF8 без BOM". Итак, пришлось написать дополнительный код, подобный указанному ниже:
//create encoding with no BOM
Encoding outputEnc = new UTF8Encoding(false);
//open file with encoding
TextWriter file = new StreamWriter(filePath, false, outputEnc);
file.Write(doc.InnerXml);
file.Flush();
file.Close(); // save and close it
В моем XML-файле заголовок выглядел так:
<?xml version="1.0" encoding="utf-16"? />
В тестовом файле я читал байты файла и декодировал данные как UTF-8 (не понимая, что заголовок в этом файле был utf-16) для создания строки.
byte[] data = Files.readAllBytes(Paths.get(path));
String dataString = new String(data, "UTF-8");
Когда я попытался десериализовать эту строку в объект, я увидел ту же ошибку:
javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,1]
Message: Content is not allowed in prolog.
Когда я обновил вторую строку
String dataString = new String(data, "UTF-16");
Я был в состоянии десериализовать объект просто отлично. Итак, как заметил Ромен выше, кодировки должны совпадать.
Удаление объявления xml решило проблему
<?xml version='1.0' encoding='utf-8'?>
Я столкнулся с той же проблемой под названием "Содержание не разрешено в прологе" в моем XML-файле.
Решение
Изначально моей корневой папкой было "#Filename".
Когда я удалил первый символ "#", ошибка была устранена.
Нет необходимости удалять #filename... Попробуйте таким образом..
Вместо передачи объекта File или URL в метод unmarshaller, используйте FileInputStream.
File myFile = new File("........");
Object obj = unmarshaller.unmarshal(new FileInputStream(myFile));
Неожиданная причина: #
символ в пути к файлу
Из-за некоторой внутренней ошибки ошибка "Недопустимое содержимое в прологе" также появляется, если содержимое файла на 100% правильно, но вы указываете имя файла следующим образом. C:\Data\#22\file.xml
,
Это может также относиться и к другим специальным символам.
Как проверить: если вы перемещаете свой файл по пути без специальных символов и ошибка исчезает, то это была проблема.
В духе "просто удалите все эти странные символы перед Xml", вот мой Java-код, который хорошо работает с вводом через BufferedReader:
BufferedReader test = new BufferedReader(new InputStreamReader(fisTest));
test.mark(4);
while (true) {
int earlyChar = test.read();
System.out.println(earlyChar);
if (earlyChar == 60) {
test.reset();
break;
} else {
test.mark(4);
}
}
FWIW, байты, которые я видел (в десятичном виде): 239, 187, 191.
Я заархивировал xml в Mac OS и отправил его на компьютер с Windows, сжатие по умолчанию изменяет эти файлы, поэтому кодировка отправила это сообщение.
Ниже приведены причины выше исключения "org.xml.sax.SAXParseException: содержимое не допускается в прологе".
- Сначала проверьте путь к файлу schema.xsd и file.xml.
- Кодировка в вашем XML и XSD (или DTD) должна быть одинаковой.
Заголовок файла XML:<?xml version='1.0' encoding='utf-8'?>
Заголовок файла XSD:<?xml version='1.0' encoding='utf-8'?>
- если что-то предшествует объявлению типа XML-документа.
hello<?xml version='1.0' encoding='utf-16'?>
случилось со мной с@JsmListener
с Spring Boot при прослушивании IBM MQ. Мой метод получил параметр и получил это исключение, когда я попытался десериализовать его с помощью JAXB.
Казалось, что строка, которую я получил, была результатомbyte[].toString()
. Это был список чисел, разделенных запятыми.
Я решил это, изменив тип параметра наbyte[]
а затем создалString
от него:
@JmsListener(destination = "Q1")
public void receiveQ1Message(byte[] msgBytes) {
var msg = new String(msgBytes);
В моем случае проблема была в том, чтобы заменить немецкие умлауты (äöü) их HTML-эквивалентами...
Я столкнулся с этим сообщением при запуске тестового примера в SoapUI:
org.xml.sax.SAXParseException; systemId: file://; lineNumber: 1; columnNumber: 1; Content is not allowed in prolog.
Через некоторое время я понял, что причина в следующей строке:
def holder = groovyUtils.getXmlHolder("SoapCall#Request") // Get Request body
И причина заключалась в том, что тестовый шаг на самом деле назывался «SOAPCall», а не «SoapCall». Я предполагаю, что возвращенная строка была пустой, что вызвало ошибку «пролог».
У меня был символ табуляции вместо пробелов. Замена вкладки '\t' устранила проблему.
Вырежьте и вставьте весь документ в редактор, такой как Notepad++, и отобразите все символы.
В моем случае у меня была проблема с build.xml
файл. Это было решено только с Build > Clean Project
,