"Вміст не заборонено в prolog" при аналізі ідеально допустимого 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 і т.д. Нічого; він проходить кожен тест на перевірку, який я міг би зробити на ньому. Навіть дивніше, це трапляється, якщо я також використовую аналізатор на саксонській основі - але ТІЛЬКИ в GAE, він завжди добре працює в моєму місцевому середовищі.

Це дуже важко відстежувати код для проблем, коли я можу запускати налагоджувач лише в середовищі, яка працює ідеально (я не знайшов жодного хорошого способу віддаленої налагодження на GAE). Тим не менш, використовуючи примітивні засоби, якими я маю, я спробував мільйон підходів, включаючи:

  • XML з прологом і без нього
  • З новими рядками та без них
  • З атрибутом "encoding =" і без нього в пролозі
  • Обидва стилі нового рядка
  • З та без інформації, яка зберігається в потоці HTTP

І я спробував більшість із них у кількох комбінаціях, де було сенс, що вони взаємодіють - нічого! Я на своєму кмітливості. Хтось бачив подібну проблему до цього, можемо сподіватися пролити трохи світла на це?

Дякую!


Напевно, нам знадобиться переглянути ще якийсь код. Інша можливість полягає в тому, що локально він не стає розбитим, поки на GAE це. Як ви обробляєте код, перш ніж передавати його в аналізатор?
Ромен Гіппо,

Я також розглядав можливість відбивання, але, мабуть, це не так, оскільки повідомлення про помилку, яке викидає аналізатор, містить весь XML прямо там (він вставлений вище). Весь модифікований код SDK можна знайти на веб- сайті github.com/AdrianP/aws-sdk-for-java (подивіться на останні останні комісії ), але там є багато коду. Я спробую незабаром створити менший відтворюваний зразок, хоча навіть це буде важко. Це велика складна частина програмного забезпечення ... Хоча дякую за відгук! :)
Адріан Петреску


@Raedwald, я не думаю, що це моє запитання - це дублікат, оскільки моє запитання було розміщено на рік раніше, ніж це :)
Адріан Петреску

1
Це повинен бути приклад того, як питання слід задавати на SO, читання його дало мені різні уявлення про те, як налагодити як розробник (спасибі ОП)
Судіп Бхандарі

Відповіді:


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 у String та оточити його "|" і роздрукувати його на консолі. Це підкаже, якщо ви переходите в кілька додаткових символів.
Ромен Гіппо,

Ах, бачу :) На жаль, я спробував це, але, здається, це не так у цій ситуації. Все одно, дякую!
Адріан Петреску

1
Дякую! Це і мене врятувало. xml.trim (). ЗамінитиFirst ("^ ([\\ W] +) <", "<");
stackoverflow

2
Хтось, будь ласка, зробить це прийнятою відповіддю. Вирішили мою проблему відразу. Я розбирав повідомлення, яке починалося з "Повідомлення: <? Xml версія ...." Проблема полягала в тексті перед бітом xml. Дякую :)
Ric Jafe

8

Це повідомлення про помилку завжди викликається недійсним вмістом XML у початковому елементі. Наприклад, додаткові маленькі точки "." на початку елемента XML

Будь-які символи перед " <?xml…." будуть викликати вище " org.xml.sax.SAXParseException: Вміст заборонено в prolog " повідомлення про помилку.

Маленька крапка " . " перед“<?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 без 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

5

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

Виправлено, зберігаючи файл у notpad ++ за допомогою Encoding (Tab)> Encode in UTF-8: selected (було кодувати в UTF-8-BOM)


3

Видалення декларації xml вирішило її

<?xml version='1.0' encoding='utf-8'?>

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");

Мені вдалося деріаріалізувати об’єкт просто чудово. Оскільки, як зазначав Ромен, кодування повинно відповідати.


1

Я зіткнувся з тією ж проблемою під назвою "Вміст заборонено в prolog" у моєму файлі xml.

Рішення

Спочатку моєю кореневою папкою було "# Ім'я файлу ".

Коли я видалив перший символ "#", помилка була усунена.

Не потрібно видаляти #filename ... Спробуйте таким чином ..

Замість того, щоб передати файл або об’єкт URL до методу unmarshaller, використовуйте FileInputStream.

File myFile = new File("........");
Object obj = unmarshaller.unmarshal(new FileInputStream(myFile));

1

Несподівана причина: #символ у шляху до файлу

Через деяку внутрішню помилку, помилка Вміст заборонено в prolog, також з’являється, якщо вміст файлу на 100% правильний, але ви надаєте ім'я файлу, якC:\Data\#22\file.xml .

Це, можливо, стосується і інших спеціальних символів.

Як перевірити: Якщо ви перемістите файл у шлях без спеціальних символів і помилка зникає, то це була ця проблема.


1

Я сьогодні схопив те саме повідомлення про помилку. Рішенням було змінити документ з UTF-8 з BOM на UTF-8 без BOM


У мене було те саме питання. Зміна формату файлу вирішила проблему. Дякую!
code_fish

0

У мене був символ вкладки замість пробілів. Заміна вкладки "\ t" усунула проблему.

Виріжте та вставте весь документ у такий редактор, як «Блокнот ++» та відобразіть усі символи.


0

У моєму випадку проблемою було рішення замінити німецькі umlauts (äöü) на їх HTML-еквіваленти ...


0

нижче наведено причину вище "org.xml.sax.SAXParseException: Вміст заборонено в prolog".

  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 типу type.ie: 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.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.