«Контент не разрешен в прологе» при синтаксическом анализе корректного XML в GAE.

109

Я бился головой об этой ужасной ошибке последние 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

И я пробовал большинство из них в нескольких комбинациях, где имело смысл их взаимодействие - ничего! Я на грани своего остроумия. Кто-нибудь видел подобную проблему раньше, которая, надеюсь, может пролить на нее свет?

Спасибо!

Адриан Петреску
источник
Возможно, нам понадобится еще немного кода. Другая возможность заключается в том, что локально он не разбивается на части, пока он есть в GAE. Как вы обрабатываете код перед тем, как передать его парсеру?
Romain Hippeau,
Я также рассматривал возможность разбиения на фрагменты, но, похоже, это не так, поскольку сообщение об ошибке, которое выдает парсер, содержит весь XML прямо здесь (он вставлен выше). Весь модифицированный код SDK можно найти на github.com/AdrianP/aws-sdk-for-java (посмотрите самые последние коммиты), но там много кода. Вскоре я постараюсь создать воспроизводимый образец меньшего размера, хотя даже это будет сложно. Это большая сложная программа ... Спасибо за ваш отзыв! :)
Адриан Петреску
@Raedwald, я не думаю, что это мой вопрос, это дубликат, так как мой вопрос был опубликован на год раньше, чем этот :)
Адриан Петреску
1
Это должен быть пример того, как следует задавать вопрос о SO, прочтение его дало мне различные представления о том, как отлаживать как разработчик (спасибо OP)
Судип Бхандари

Ответы:

129

Кодировка в вашем 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"?>  

или даже пробел или специальный символ.

Есть некоторые специальные символы, называемые маркерами порядка байтов, которые могут находиться в буфере. Перед передачей буфера в парсер сделайте следующее ...

String xml = "<?xml ...";
xml = xml.trim().replaceFirst("^([\\W]+)<","<");
Ромен Иппо
источник
Привет, Ромен, спасибо за ответ! Я дважды и трижды проверял много раз на наличие чего-либо в буфере перед прологом (включая скрытые символы), но там просто больше ничего нет. Однако я попробую переключиться на кодировку utf-16 - из любопытства, откуда вы взяли информацию, что XSD использует UTF-16?
Адриан Петреску,
@Adrian Petrescu Извините, это всего лишь примеры. Если вы используете DTD или XSD, убедитесь, что они соответствуют вашему XML. Перед синтаксическим анализом XML запишите его в строку и заключите в "|" и распечатайте его на консоли. Это скажет вам, пропустили ли вы какие-то лишние символы.
Romain Hippeau,
Ах, понятно :) К сожалению, я попробовал, и в данной ситуации, похоже, это не так. Спасибо, в любом случае!
Адриан Петреску,
1
Спасибо! Это меня тоже спасло. xml.trim (). replaceFirst ("^ ([\\ W] +) <", "<");
stackoverflow
2
Кто-нибудь, пожалуйста, сделайте это принятым ответом. Решил мою проблему сразу. Я разбирал сообщение, которое начиналось с «Сообщение: <? Xml version ....». Проблема заключалась в тексте перед битом xml. Спасибо :)
Ric Jafe
8

Это сообщение об ошибке всегда вызвано недопустимым содержимым XML в начальном элементе. Например, очень маленькая точка «.» в начале элемента XML.

Любые символы перед « <?xml….» вызовут сообщение об ошибке « org.xml.sax.SAXParseException: содержимое не разрешено в прологе ».

Маленькая точка » . " перед“<?xml….

Чтобы исправить это, просто удалите все эти странные символы перед расширением “<?xml“.

Ссылка: http://www.mkyong.com/java/sax-error-content-is-not-allowed-in-prolog/

Санмит Гирме
источник
3
Вы должны упомянуть, где вы упомянули, что mkyong.com/java/sax-error-content-is-not-allowed-in-prolog
arulraj.net
5

Я столкнулся с той же проблемой. В моем случае файлы XML были созданы из программы на C # и загружены в AS400 для дальнейшей обработки. После некоторого анализа было установлено, что я использовал кодировку UTF8 при создании файлов XML, тогда как javac (в AS400) использует «UTF8 без спецификации». Итак, пришлось написать дополнительный код, подобный упомянутому ниже:

//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
Сатурн CAU
источник
5

У меня возникла проблема при проверке файла xml в блокноте ++ и сохранении файла, хотя у меня был верхний тег xml utf-8 как <?xml version="1.0" encoding="utf-8"?>

Исправлено сохранением файла в notpad ++ с помощью Encoding (Tab)> Encode in UTF-8: selected (было Encode in UTF-8-BOM)

techloris_109
источник
3

Удаление объявления xml решило это

<?xml version='1.0' encoding='utf-8'?>
FOO
источник
2

В моем 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");

Мне удалось десериализовать объект очень хорошо. Итак, как заметил выше Ромен, кодировки должны совпадать.

Dfritch
источник
1

Я столкнулся с той же проблемой под названием «Контент не разрешен в прологе» в моем XML-файле.

Решение

Изначально моя корневая папка была «# Имя файла ».

Когда я удалил первый символ «#», ошибка исчезла.

Нет необходимости удалять #filename ... Попробуйте так ..

Вместо передачи объекта File или URL методу unmarshaller используйте FileInputStream.

File myFile = new File("........");
Object obj = unmarshaller.unmarshal(new FileInputStream(myFile));
Рави Киран
источник
1

Неожиданная причина: #символ в пути к файлу

Из-за некоторой внутренней ошибки ошибка Content is not allowed in prolog также появляется, если само содержимое файла на 100% правильное, но вы указываете имя файла, например C:\Data\#22\file.xml.

Это может относиться и к другим специальным символам.

Как проверить: если вы переместите свой файл по пути без специальных символов и ошибка исчезнет, ​​значит, это была эта проблема.

Miroxlav
источник
1

Сегодня я поймал такое же сообщение об ошибке. Решением было изменить документ с UTF-8 с BOM на UTF-8 без BOM.

Matjung
источник
Я была такая же проблема. Изменение формата файла устранило проблему. Спасибо!
code_fish
0

У меня был символ табуляции вместо пробелов. Замена вкладки '\ t' устранила проблему.

Вырежьте и вставьте весь документ в редактор, например Notepad ++, и отобразите все символы.

SoloPilot
источник
0

В моем случае проблемы решением было заменить немецкие умляуты (äöü) их HTML-эквивалентами ...

MBaas
источник
0

ниже приведена причина выше исключения «org.xml.sax.SAXParseException: содержимое не допускается в прологе».

  1. Сначала проверьте путь к файлам schema.xsd и file.xml.
  2. Кодировка в вашем XML и XSD (или DTD) должна быть одинаковой.
    Заголовок файла XML: <?xml version='1.0' encoding='utf-8'?>
    Заголовок файла XSD:<?xml version='1.0' encoding='utf-8'?>
  3. если что-либо предшествует объявлению типа документа XML. т.е. hello<?xml version='1.0' encoding='utf-16'?>
Авинаш Дубей
источник
0

В духе «просто удалите все эти странные символы перед <? 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.

Тамиас
источник