"Konten tidak diperbolehkan dalam prolog" saat mengurai XML yang benar-benar valid di GAE

109

Saya telah memukuli kepala saya terhadap bug yang benar-benar menyebalkan ini selama 48 jam terakhir, jadi saya pikir akhirnya saya menyerah dan mencoba bertanya di sini sebelum saya membuang laptop saya ke luar jendela.

Saya mencoba mengurai XML tanggapan dari panggilan yang saya lakukan ke AWS SimpleDB. Tanggapannya datang kembali dengan baik; misalnya, mungkin terlihat seperti:

<?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>

Saya mengirimkan XML ini ke parser dengan

XMLEventReader eventReader = xmlInputFactory.createXMLEventReader(response.getContent());

dan menelepon eventReader.nextEvent();berkali-kali untuk mendapatkan data yang saya inginkan.

Inilah bagian yang aneh - ini berfungsi dengan baik di dalam server lokal. Tanggapannya masuk, saya parse, semua orang senang. Masalahnya adalah saat saya menerapkan kode ke Google App Engine, permintaan keluar masih berfungsi, dan XML responsnya tampak 100% identik dan benar bagi saya, tetapi respons gagal diurai dengan pengecualian berikut:

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)

Saya memiliki double, triple, quadruple memeriksa XML ini untuk 'karakter tak terlihat' atau karakter non-UTF8 yang dikodekan, dll. Saya melihatnya byte-by-byte dalam array untuk byte-order-marks atau sesuatu yang bersifat seperti itu. Tidak ada; itu melewati setiap tes validasi yang bisa saya lakukan. Lebih aneh lagi, itu terjadi jika saya juga menggunakan parser berbasis Saxon - tetapi HANYA pada GAE, ini selalu berfungsi dengan baik di lingkungan lokal saya.

Itu membuat sangat sulit untuk melacak kode untuk masalah ketika saya hanya dapat menjalankan debugger di lingkungan yang bekerja dengan sempurna (saya belum menemukan cara yang baik untuk men-debug dari jarak jauh di GAE). Namun demikian, dengan menggunakan cara primitif yang saya miliki, saya telah mencoba jutaan pendekatan termasuk:

  • XML dengan dan tanpa prolog
  • Dengan dan tanpa baris baru
  • Dengan dan tanpa atribut "encoding =" di prolog
  • Keduanya gaya baris baru
  • Dengan dan tanpa informasi chunking yang ada di aliran HTTP

Dan saya sudah mencoba sebagian besar dari ini dalam berbagai kombinasi yang masuk akal jika mereka berinteraksi - tidak ada! Aku kehabisan akal. Adakah yang pernah melihat masalah seperti ini sebelumnya yang semoga dapat menjelaskannya?

Terima kasih!

Adrian Petrescu
sumber
Kami mungkin perlu melihat beberapa kode lagi. Kemungkinan lain adalah bahwa secara lokal itu tidak dipotong sementara di GAE itu. Bagaimana Anda menangani kode sebelum Anda meneruskannya ke parser?
Romain Hippeau
Saya mempertimbangkan kemungkinan chunking juga, tetapi tampaknya tidak demikian karena pesan kesalahan yang dilempar parser berisi seluruh XML di sana (ditempel di atas). Seluruh kode SDK yang dimodifikasi dapat ditemukan di github.com/AdrianP/aws-sdk-for-java (lihat komit terbaru) tetapi ada BANYAK kode di sana. Saya akan mencoba membuat sampel kecil yang dapat direproduksi segera, meskipun itu pun akan sulit. Ini adalah perangkat lunak yang sangat rumit ... Terima kasih atas tanggapan Anda! :)
Adrian Petrescu
@Raedwald, saya rasa bukan pertanyaan saya yang duplikatnya, karena pertanyaan saya diposting setahun lebih awal dari yang itu :)
Adrian Petrescu
1
Ini harus menjadi contoh bagaimana pertanyaan harus ditanyakan pada SO, membacanya memberi saya berbagai wawasan tentang bagaimana melakukan debug sebagai pengembang (terima kasih OP)
Sudip Bhandari

Jawaban:

129

Pengkodean dalam XML dan XSD (atau DTD) Anda berbeda.
Judul file XML: <?xml version='1.0' encoding='utf-8'?>
header file XSD:<?xml version='1.0' encoding='utf-16'?>

Skenario lain yang mungkin menyebabkan ini adalah ketika sesuatu datang sebelum deklarasi tipe dokumen XML. yaitu Anda mungkin memiliki sesuatu seperti ini di buffer:

helloworld<?xml version="1.0" encoding="utf-8"?>  

atau bahkan spasi atau karakter khusus.

Ada beberapa karakter khusus yang disebut penanda urutan byte yang mungkin ada di buffer. Sebelum meneruskan buffer ke Parser, lakukan ini ...

String xml = "<?xml ...";
xml = xml.trim().replaceFirst("^([\\W]+)<","<");
Romain Hippeau
sumber
Hai Romain, terima kasih atas tanggapannya! Saya telah memeriksa dua dan tiga kali berkali-kali untuk apa pun di buffer sebelum prolog (termasuk karakter tersembunyi) tetapi tidak ada yang lain di sana. Saya akan mencoba beralih ke pengkodean utf-16, namun - karena penasaran, dari mana Anda mendapatkan informasi bahwa XSD menggunakan UTF-16?
Adrian Petrescu
@Adrian Petrescu Maaf, ini hanya contoh Jika Anda menggunakan DTD atau XSD pastikan cocok dengan XML Anda. Sebelum Anda mem-parsing XML, tangkap dalam String dan kelilingi dengan '|' dan mencetaknya ke konsol. Ini akan memberi tahu Anda jika Anda memasukkan beberapa karakter tambahan.
Romain Hippeau
Ah, saya mengerti :) Sayangnya saya mencobanya dan tampaknya tidak menjadi masalah dalam situasi ini. Terima kasih!
Adrian Petrescu
1
Terima kasih! Ini menyelamatkan saya juga. xml.trim (). replaceFirst ("^ ([\\ W] +) <", "<");
stackoverflow
2
Seseorang tolong jadikan ini jawaban yang diterima. Memecahkan masalah saya dengan segera. Saya sedang mengurai Pesan yang dimulai dengan "Pesan: <? Versi xml ...." Masalahnya adalah teks sebelum bit xml. Terima kasih :)
Ric Jafe
8

Pesan kesalahan ini selalu disebabkan oleh konten XML yang tidak valid di elemen awal. Misalnya, titik ekstra kecil “.” di awal elemen XML.

Karakter apa pun sebelum " <?xml…." akan menyebabkan di atas " org.xml.sax.SAXParseException: Konten tidak diizinkan dalam prolog " pesan kesalahan.

Titik kecil “ . " sebelum“<?xml….

Untuk memperbaikinya, hapus saja semua karakter aneh itu sebelum “<?xml“.

Ref: http://www.mkyong.com/java/sax-error-content-is-not-allowed-in-prolog/

Sunmit Girme
sumber
3
Anda harus menyebutkan di mana Anda merujuk bahwa mkyong.com/java/sax-error-content-is-not-allowed-in-prolog
arulraj.net
5

Saya menghadapi masalah yang sama. Dalam kasus saya, file XML dihasilkan dari program c # dan dimasukkan ke dalam AS400 untuk diproses lebih lanjut. Setelah beberapa analisis mengidentifikasi bahwa saya menggunakan pengkodean UTF8 saat membuat file XML sedangkan javac (dalam AS400) menggunakan "UTF8 tanpa BOM". Jadi, harus menulis kode tambahan yang mirip dengan yang disebutkan di bawah ini:

//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
Saturnus CAU
sumber
5

Saya mengalami masalah saat memeriksa file xml di notepad ++ dan menyimpan file, meskipun saya memiliki tag utf-8 xml teratas sebagai <?xml version="1.0" encoding="utf-8"?>

Diperbaiki dengan menyimpan file di notpad ++ dengan Encoding (Tab)> Encode in UTF-8: dipilih (sebelumnya Encode in UTF-8-BOM)

techloris_109
sumber
3

Menghapus deklarasi xml menyelesaikannya

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

Di file xml saya, tajuknya terlihat seperti ini:

<?xml version="1.0" encoding="utf-16"? />

Dalam file uji, saya membaca file byte dan mendekode data sebagai UTF-8 (tidak menyadari bahwa header dalam file ini adalah utf-16) untuk membuat string.

byte[] data = Files.readAllBytes(Paths.get(path));
String dataString = new String(data, "UTF-8");

Ketika saya mencoba deserialisasi string ini menjadi objek, saya melihat kesalahan yang sama:

javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,1]
Message: Content is not allowed in prolog.

Saat saya memperbarui baris kedua menjadi

String dataString = new String(data, "UTF-16");

Saya bisa mendesialisasi objek dengan baik. Jadi, seperti yang disebutkan Romain di atas, pengkodean harus cocok.

dfritch.dll
sumber
1

Saya menghadapi masalah yang sama yang disebut "Konten tidak diperbolehkan dalam prolog" di file xml saya.

Larutan

Awalnya folder root saya adalah '# Filename '.

Ketika saya menghapus karakter pertama '#', kesalahan teratasi.

Tidak perlu menghapus #filename ... Coba cara ini ..

Alih-alih meneruskan File atau objek URL ke metode unmarshaller, gunakan FileInputStream.

File myFile = new File("........");
Object obj = unmarshaller.unmarshal(new FileInputStream(myFile));
Ravi Kiran
sumber
1

Alasan tak terduga: #karakter di jalur file

Karena beberapa bug internal, kesalahan Konten tidak diperbolehkan dalam prolog juga muncul jika konten file itu sendiri 100% benar tetapi Anda memberikan nama file seperti C:\Data\#22\file.xml.

Ini mungkin juga berlaku untuk karakter khusus lainnya.

Cara memeriksa: Jika Anda memindahkan file Anda ke jalur tanpa karakter khusus dan kesalahan hilang, maka itulah masalah ini.

miroxlav.dll
sumber
1

Saya menangkap pesan kesalahan yang sama hari ini. Solusinya adalah mengganti dokumen dari UTF-8 dengan BOM menjadi UTF-8 tanpa BOM

matjung
sumber
Saya memiliki masalah yang sama. Mengubah format file menyelesaikan masalah. Terima kasih!
code_fish
0

Saya memiliki karakter tab, bukan spasi. Mengganti tab '\ t' memperbaiki masalah.

Potong dan tempel seluruh dokumen ke editor seperti Notepad ++ dan tampilkan semua karakter.

SoloPilot
sumber
0

Dalam contoh masalah saya, solusinya adalah mengganti umlaut Jerman (äöü) dengan padanan HTML mereka ...

MBaas
sumber
0

di bawah ini adalah penyebab di atas pengecualian “org.xml.sax.SAXParseException: Konten tidak diperbolehkan dalam prolog”.

  1. Pertama periksa jalur file schema.xsd dan file.xml.
  2. Pengkodean dalam XML dan XSD (atau DTD) Anda harus sama.
    Judul file XML: <?xml version='1.0' encoding='utf-8'?>
    header file XSD:<?xml version='1.0' encoding='utf-8'?>
  3. jika ada yang datang sebelum deklarasi tipe dokumen XML: hello<?xml version='1.0' encoding='utf-16'?>
Avinash Dubey
sumber
0

Dalam semangat "hapus saja semua karakter aneh itu sebelum <? Xml", inilah kode Java saya, yang bekerja dengan baik dengan input melalui 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, byte yang saya lihat adalah (dalam desimal): 239, 187, 191.

Tamias
sumber