GAE'de mükemmel şekilde geçerli XML ayrıştırılırken "içeriğe prolog'da izin verilmez"


109

Son 48 saattir bu kesinlikle çileden çıkaran böceğe karşı kafamı dövüyordum, bu yüzden sonunda havluyu atıp dizüstü bilgisayarımı pencereden atmadan önce burada sormayı deneyeceğimi düşündüm.

AWS SimpleDB'ye yaptığım bir çağrıdaki yanıt XML'sini ayrıştırmaya çalışıyorum. Cevap tele gayet iyi geliyor; örneğin şöyle görünebilir:

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

Bu XML'yi bir ayrıştırıcıya iletiyorum

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

ve eventReader.nextEvent();istediğim verileri almak için birkaç kez arayın .

İşte tuhaf kısım - yerel sunucu içinde harika çalışıyor. Cevap geliyor, ayrıştırıyorum, herkes mutlu. Sorun şu ki, kodu Google App Engine'e dağıttığımda, giden istek hala çalışıyor ve yanıt XML benim için% 100 aynı ve doğru görünüyor, ancak yanıt aşağıdaki istisna ile ayrıştırılamıyor:

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)

Bu XML'de 'görünmez karakterler' veya UTF8 olmayan kodlanmış karakterler, vb. İçin çift, üçlü, dörtlü kontrol ettim. Bayt sıra işaretleri veya bu türden bir şey için bir dizide bayt bayt'a baktım. Hiçbir şey değil; atabileceğim her doğrulama testini geçti. Daha da garip, Sakson tabanlı bir ayrıştırıcı kullanırsam da olur - ancak YALNIZCA GAE'de, yerel ortamımda her zaman iyi çalışır.

Hata ayıklayıcıyı yalnızca mükemmel şekilde çalışan bir ortamda çalıştırabildiğimde (GAE'de uzaktan hata ayıklamanın iyi bir yolunu bulamadım) sorunlara yönelik kodu izlemeyi çok zorlaştırıyor. Yine de, sahip olduğum ilkel araçları kullanarak, aşağıdakileri içeren bir milyon yaklaşım denedim:

  • Prolog içeren ve içermeyen XML
  • Satırsonu olan ve olmayan
  • Prologdaki "encoding =" özelliği olsun veya olmasın
  • Her iki satırsonu stili
  • HTTP akışında bulunan yığın bilgileri varken ve yokken

Ve bunların çoğunu, etkileşim kuracaklarının mantıklı olduğu çoklu kombinasyonlarda denedim - hiçbir şey! Aklımın sonundayım. Daha önce böyle bir sorunu gören var mı, umarım bu konuya biraz ışık tutabilir mi?

Teşekkürler!


Muhtemelen biraz daha kod görmemiz gerekecek. Diğer bir olasılık da, yerel olarak GAE üzerindeyken parçalanmamasıdır. Ayrıştırıcıya iletmeden önce kodu nasıl kullanıyorsunuz?
Romain Hippeau

Parçalama olasılığını da düşündüm, ancak çözümleyicinin attığı hata mesajı tam XML'yi içerdiğinden (yukarıya yapıştırıldı) durum böyle görünmüyor. Değiştirilmiş SDK kodunun tamamı github.com/AdrianP/aws-sdk-for-java adresinde bulunabilir (en son kayıtlara bakın), ancak orada çok sayıda kod var. Yakında daha küçük tekrarlanabilir bir örnek oluşturmaya çalışacağım, ancak bu bile zor olacak. Bu büyük ve karmaşık bir yazılım parçası ... Yine de geri bildiriminiz için teşekkürler! :)
Adrian Petrescu


@Raedwald, sorumun kopyası olduğunu sanmıyorum, çünkü sorum ondan bir yıl önce yayınlandı :)
Adrian Petrescu

1
Bu, SO'da bir sorunun nasıl sorulması gerektiğinin bir örneği olmalı, onu okumak bana bir geliştirici olarak nasıl hata ayıklayacağım konusunda çeşitli bilgiler verdi (teşekkürler OP)
Sudip Bhandari

Yanıtlar:


129

XML ve XSD'nizdeki (veya DTD) kodlama farklıdır.
XML dosyası başlığı: <?xml version='1.0' encoding='utf-8'?>
XSD dosyası başlığı:<?xml version='1.0' encoding='utf-16'?>

Buna neden olan başka bir olası senaryo, herhangi bir şeyin XML belge türü bildiriminden önce gelmesidir. yani, arabellekte buna benzer bir şey olabilir:

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

hatta bir boşluk veya özel bir karakter.

Tamponda olabilecek bayt sırası işaretçileri adı verilen bazı özel karakterler vardır. Tamponu Ayrıştırıcıya aktarmadan önce bunu yapın ...

String xml = "<?xml ...";
xml = xml.trim().replaceFirst("^([\\W]+)<","<");

Merhaba Romain, cevabınız için teşekkürler! Prologdan önce tampondaki herhangi bir şeyi (gizli karakterler dahil) birçok kez iki ve üç kez kontrol ettim, ancak orada başka hiçbir şey yok. Bununla birlikte, utf-16 kodlamasına geçiş yapmayı deneyeceğim - meraktan, XSD'nin UTF-16 kullandığı bilgisini nereden aldınız?
Adrian Petrescu

@Adrian Petrescu Üzgünüz, bunlar sadece örnekler DTD'ler veya XSD'ler kullanıyorsanız bunların XML'inizle eşleştiğinden emin olun. XML'yi ayrıştırmadan önce onu bir String içinde yakalayın ve '|' ile çevreleyin. ve konsola yazdırın. Bu size fazladan bazı karakterler geçip geçmediğinizi söyleyecektir.
Romain Hippeau

Ah, görüyorum :) Maalesef denedim ve bu durumda öyle görünmüyor. Yine de teşekkürler!
Adrian Petrescu

1
Teşekkürler! Bu beni de kurtardı. xml.trim (). replaceFirst ("^ ([\\ W] +) <", "<");
stackoverflow

2
Lütfen birisi bunu kabul edilen cevap yapsın. Sorunumu hemen çözdüm. "İleti: <? Xml sürümü ...." ile başlayan bir İletiyi ayrıştırıyordum. Sorun, xml bitinden önceki metindi. Teşekkürler :)
Ric Jafe

8

Bu hata mesajı her zaman başlangıç ​​öğesindeki geçersiz XML içeriğinden kaynaklanır. Örneğin, çok küçük nokta "." XML öğesinin başında.

" <?xml…." Öncesindeki herhangi bir karakter yukarıdaki " org.xml.sax.SAXParseException: Prolog'da içeriğe izin verilmiyor " hata mesajına neden olur.

Küçük bir nokta " . " önce“<?xml….

Düzeltmek için, önündeki tüm garip karakterleri silin “<?xml“.

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



5

Ben de aynı sorunla karşı karşıyaydım. Benim durumumda XML dosyaları c # programından oluşturuldu ve daha sonraki işlemler için AS400'e beslendi. Bazı analizlerden sonra XML dosyalarını oluştururken UTF8 kodlamasını kullandığımı belirledikten sonra javac (AS400'de) "BOM'suz UTF8" kullanıyor. Bu nedenle, aşağıda belirtilene benzer ekstra kod yazmamız gerekiyordu:

//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 dosyasını notepad ++ 'da incelerken ve dosyayı kaydederken sorun yaşadım, ancak şu şekilde en iyi utf-8 xml etiketim vardı <?xml version="1.0" encoding="utf-8"?>

Dosyayı Kodlama (Sekme)> UTF-8'de Kodlama ile notpad ++ 'da kaydederek düzeltildi: seçildi (UTF-8-BOM'da Kodlandı)


3

Xml bildirimini kaldırmak sorunu çözdü

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

2

Xml dosyamda başlık şuna benziyordu:

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

Bir test dosyasında, bir dize oluşturmak için dosya baytlarını okuyordum ve verileri UTF-8 olarak çözüyordum (bu dosyadaki başlığın utf-16 olduğunu fark etmemiştim).

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

Bu dizeyi bir nesneye dönüştürmeye çalıştığımda, aynı hatayı görüyordum:

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

İkinci satırı güncellediğimde

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

Nesnenin seri halini kaldırmayı gayet iyi başardım. Romain'in yukarıda belirttiği gibi, kodlamaların eşleşmesi gerekir.


1

Xml dosyamda "İçeriğe prolog'da izin verilmiyor" adlı aynı sorunla karşılaşıyordum.

Çözüm

Başlangıçta kök klasörüm '# Dosya Adı ' idi.

İlk '#' karakterini kaldırdığımda hata çözüldü.

# Dosya adını kaldırmaya gerek yok ... Bu şekilde deneyin ..

Unmarshaller yöntemine bir File veya URL nesnesi geçirmek yerine, bir FileInputStream kullanın.

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

1

Beklenmeyen neden: #dosya yolundaki karakter

Bazı iç hatadan, hata nedeniyle İçerik önbölüküne izin verilmez dosya içeriği kendisi% 100 doğru ama böyle bir dosya adı vermekteyiz eğer de görünür C:\Data\#22\file.xml.

Bu muhtemelen diğer özel karakterler için de geçerli olabilir.

Nasıl kontrol edilir: Dosyanızı özel karakterlerin olmadığı bir yola taşırsanız ve hata kaybolursa, sorun budur.


1

Bugün aynı hata mesajını yakaladım. Çözüm, belgeyi BOM içeren UTF-8'den BOM olmadan UTF-8'e değiştirmekti


Ben de aynı sorunu yaşadım. Dosya formatının değiştirilmesi sorunu çözdü. Teşekkürler!
code_fish

0

Boşluk yerine sekme karakterim vardı. '\ T' sekmesinin değiştirilmesi sorunu çözdü.

Tüm dokümanı kesin ve Notepad ++ gibi bir düzenleyiciye yapıştırın ve tüm karakterleri görüntüleyin.


0

Benim sorunum örneğinde, çözüm, almanca umlautları (äöü) HTML eşdeğerleriyle değiştirmekti ...


0

"org.xml.sax.SAXParseException: İçeriğe prolog'da izin verilmez" istisnasının üstündeki nedendir.

  1. Öncelikle schema.xsd ve file.xml dosyalarının yolunu kontrol edin.
  2. XML ve XSD'nizdeki (veya DTD) kodlama aynı olmalıdır.
    XML dosyası başlığı: <?xml version='1.0' encoding='utf-8'?>
    XSD dosyası başlığı:<?xml version='1.0' encoding='utf-8'?>
  3. XML belge türü bildiriminden önce herhangi bir şey gelirse: hello<?xml version='1.0' encoding='utf-16'?>

0

"<? Xml'den önceki tüm bu garip karakterleri sil" ruhuyla, işte Tamponlu Okuyucu aracılığıyla girişle iyi çalışan Java kodum:

    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, gördüğüm baytlar (ondalık olarak): 239, 187, 191.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.