Съдържанието не е разрешено в пролог, когато се анализира напълно валиден 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 потока

И пробвах повечето от тях в множество комбинации, където имаше смисъл да си взаимодействат -- нищо! Аз съм на края на акъла си. Някой виждал ли е подобен проблем преди, който да се надяваме да хвърли малко светлина върху него?

Благодаря!


person Adrian Petrescu    schedule 13.06.2010    source източник
comment
Вероятно ще трябва да видим още код. Друга възможност е, че локално не се нарязва на парчета, докато е на GAE. Как се справяте с кода, преди да го предадете на анализатора?   -  person Romain Hippeau    schedule 13.06.2010
comment
Обмислих и възможността за разделяне, но изглежда не е така, тъй като съобщението за грешка, което анализаторът хвърля, съдържа целия XML точно там (поставен е по-горе). Целият модифициран SDK код може да бъде намерен на github.com/AdrianP/aws-sdk-for -java (вижте най-новите комити), но там има МНОГО код. Ще се опитам скоро да създам по-малка възпроизводима проба, въпреки че дори това ще бъде трудно. Това е много сложен софтуер... Все пак благодаря за обратната връзка! :)   -  person Adrian Petrescu    schedule 13.06.2010
comment
възможен дубликат на org.xml.sax.SAXParseException: Съдържание не е позволено в пролог   -  person Raedwald    schedule 18.07.2014
comment
@Raedwald, не мисля, че въпросът ми е дубликат, тъй като въпросът ми беше публикуван година по-рано от този :)   -  person Adrian Petrescu    schedule 18.07.2014
comment
Другият въпрос е по-полезен като каноничен въпрос, тъй като е по-общ.   -  person Raedwald    schedule 19.07.2014
comment
@AdrianPetrescu вижте този отговор на MSE: meta.stackexchange.com/a/147651/170084   -  person Raedwald    schedule 19.07.2014
comment
Това трябва да е пример за това как трябва да бъде зададен въпрос на SO, четенето му ми даде различни прозрения за това как да отстранявам грешки като разработчик (благодаря OP)   -  person Sudip Bhandari    schedule 02.01.2018


Отговори (14)


Кодирането във вашия 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]+)<","<");
person Romain Hippeau    schedule 13.06.2010
comment
Здравей Ромен, благодаря за отговора! Проверих двойно и тройно много пъти за нещо в буфера преди пролога (включително скрити символи), но там просто няма нищо друго. Ще опитам да превключа към utf-16 кодиране обаче - от любопитство откъде взехте информацията, че XSD използва UTF-16? - person Adrian Petrescu; 13.06.2010
comment
@Adrian Petrescu Съжаляваме, това са само примери. Ако използвате DTD или XSD, уверете се, че съвпадат с вашия XML. Преди да анализирате XML, запишете го в низ и го оградете с '|' и го отпечатайте на конзолата. Това ще ви каже дали предавате допълнителни знаци. - person Romain Hippeau; 13.06.2010
comment
А, разбирам :) За съжаление го пробвах и не изглежда да е така в тази ситуация. Благодаря все пак! - person Adrian Petrescu; 13.06.2010
comment
@Adrian Petrescu Актуализирах публикацията си, за да опитате нещо друго. Променете своя XMLEventReader eventReader = xmlInputFactory.createXMLEventReader(response.getContent()); към ... String xml = response.getContent(); xml = xml.trim().replaceFirst(^([\\W]+)‹,‹); XMLEventReader eventReader = xmlInputFactory.createXMLEventReader(xml); - person Romain Hippeau; 13.06.2010
comment
Благодаря, скоро ще опитам това, въпреки че вече проверих за маркировки за ред на байтове; може би се въвеждат някъде между входния поток и XMLReader. - person Adrian Petrescu; 13.06.2010
comment
helloworld‹?xml version=1.0 encoding=utf-8?› [нещо преди ‹?xml .. ] работи за мен - person Piyush Patel; 10.05.2012
comment
Благодаря! Това ме спаси и мен. xml.trim().replaceFirst(^([\\W]+)‹,‹); - person stackoverflow; 25.01.2013
comment
Моля, някой да направи това приет отговор. Реши проблема ми веднага. Анализирах съобщение, което започваше със Съобщение: ‹?xml версия.... Проблемът беше текстът преди xml бита. Благодаря :) - person Ric Jafe; 20.02.2013
comment
Това решава проблема ми, с който се сблъсквам с xml емисия от един сайт. Но прекъсва за друг URL адрес, където анализаторът не е имал проблем по-рано. Не мога да разбера точно какво прави регулярният израз: ^([\\W]+)‹. Получавам XML от входен поток. Моля, обяснете как точно работи този регулярен израз. - person codeMan; 10.09.2013
comment
@codeMan регулярният израз замества всички начални бели интервали и започващи ‹ с ‹ - person Romain Hippeau; 10.09.2013
comment
@AdrianPetrescu, моля, направете това като приет отговор. Това реши проблема ми! - person dimuthu; 02.07.2014
comment
@Raedwald сравнете датите. Това беше отговорено преди 3 години. - person Romain Hippeau; 18.07.2014
comment
@RomainHippeau вижте този отговор на MSE: meta.stackexchange.com/a/147651/170084 - person Raedwald; 19.07.2014
comment
@RomainHippeau utf-16 беше :P Благодаря за чудесния отговор. - person Dayan; 24.12.2015
comment
Имах и случай, в който герой в края на пролога причиняваше проблема. Получавах XML съобщения, където те поставяха точка след всяко ›, така ›. Това води до първи ред, който изглежда така: ‹?xml version=1.0 encoding=UTF-8 standalone=yes?›. - person BigMac66; 09.02.2016
comment
@ Romain Можем да променим кодирането с помощта на Notepad++. Ще работи ли тогава? - person vts; 04.07.2017
comment
@peter може би, но аз описвам два възможни проблема в моя отговор. - person Romain Hippeau; 04.07.2017
comment
В моя случай имаше скрит знак в предишния ‹?xml, който не беше показан от редактора, което причини проблема. - person darkman97i; 19.11.2018

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

Поправено е чрез запазване на файла в notpad++ с Encoding(Tab) > Encode in UTF-8:selected (беше Encode in UTF-8-BOM)

person techloris_109    schedule 27.07.2018

Това съобщение за грешка винаги се причинява от невалидно XML съдържание в началния елемент. Например допълнителна малка точка „.“ в началото на XML елемент.

Всички знаци преди „<?xml….“ ще доведат до съобщение за грешка „org.xml.sax.SAXParseException: Съдържанието не е разрешено в пролога“.

Малка точка „.“ преди “<?xml….

За да го поправите, просто изтрийте всички онези странни знаци преди “<?xml“.

Справка: http://www.mkyong.com/java/sax-error-content-is-not-allowed-in-prolog/

person Sunmit Girme    schedule 07.05.2013
comment
Трябва да споменете къде сте посочили този mkyong. com/java/sax-error-content-is-not-allowed-in-prolog - person arulraj.net; 16.07.2014

Бях изправен пред същия проблем. В моя случай 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
person Saturn CAU    schedule 23.05.2014

Хванах същото съобщение за грешка днес. Решението беше да се промени документът от UTF-8 с BOM на UTF-8 без BOM

person matjung    schedule 13.10.2019
comment
Имах същия проблем. Промяната на файловия формат реши проблема. Благодаря! - person code_fish; 25.06.2020

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

Успях да десериализирам обекта добре. Така че, както Ромен отбеляза по-горе, кодировките трябва да съвпадат.

person dfritch    schedule 09.02.2015

Премахването на xml декларацията го реши

<?xml version='1.0' encoding='utf-8'?>
person F.O.O    schedule 18.07.2018

Бях изправен пред същия проблем, наречен „Съдържанието не е разрешено в prolog“ в моя xml файл.

Решение

Първоначално основната ми папка беше „#Име на файл“.

Когато премахнах първия знак '#', грешката беше разрешена.

Няма нужда да премахвате #filename... Опитайте по този начин..

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

File myFile = new File("........");
Object obj = unmarshaller.unmarshal(new FileInputStream(myFile));
person Ravi Kiran Gururaja    schedule 23.01.2015

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

Поради някакъв вътрешен бъг грешката Съдържанието не е разрешено в пролога също се появява, ако самото съдържание на файла е 100% правилно, но вие предоставяте името на файла като C:\Data\#22\file.xml.

Това може да се отнася и за други специални символи.

Как да проверите: Ако преместите файла си в път без специални знаци и грешката изчезне, значи проблемът е бил този.

person miroxlav    schedule 19.02.2019

Имах табулатор вместо интервали. Замяната на раздела „\t“ реши проблема.

Изрежете и поставете целия документ в редактор като Notepad++ и покажете всички знаци.

person SoloPilot    schedule 21.08.2013

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

person MBaas    schedule 21.02.2015

по-долу са причините по-горе „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'?>
person Avinash Dubey    schedule 12.12.2016

В духа на „просто изтрийте всички онези странни знаци преди ‹?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.

person Tamias    schedule 13.06.2018

Компресирах xml в Mac OS и го изпратих на машина с Windows, компресията по подразбиране променя тези файлове, така че кодирането изпрати това съобщение.

person htafoya    schedule 05.01.2021