"Il contenuto non è consentito nel prologo" durante l'analisi di XML perfettamente valido su GAE


109

Ho battuto la testa contro questo bug assolutamente esasperante nelle ultime 48 ore, quindi ho pensato di gettare la spugna e provare a chiedere qui prima di gettare il mio laptop dalla finestra.

Sto cercando di analizzare l'XML di risposta da una chiamata che ho effettuato ad AWS SimpleDB. La risposta sta tornando sul filo più che bene; ad esempio, potrebbe essere simile a:

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

Passo questo XML a un parser con

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

e chiamare eventReader.nextEvent();un sacco di volte per ottenere i dati che desidero.

Ecco la parte bizzarra: funziona benissimo all'interno del server locale. La risposta arriva, lo analizzo, tutti sono felici. Il problema è che quando distribuisco il codice su Google App Engine, la richiesta in uscita funziona ancora e l'XML di risposta mi sembra identico e corretto al 100%, ma la risposta non viene analizzata con la seguente eccezione:

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)

Ho controllato due volte, tre volte, quadruplicare questo XML per "caratteri invisibili" o caratteri non codificati UTF8, ecc. L'ho guardato byte per byte in un array per i segni dell'ordine dei byte o qualcosa del genere. Niente; supera tutti i test di convalida che potrei lanciargli. Ancora più strano, succede se utilizzo anche un parser basato su Saxon - ma SOLO su GAE, funziona sempre bene nel mio ambiente locale.

Rende molto difficile tracciare il codice per i problemi quando posso eseguire il debugger solo su un ambiente che funziona perfettamente (non ho trovato alcun buon modo per eseguire il debug remoto su GAE). Tuttavia, utilizzando i mezzi primitivi che ho, ho provato un milione di approcci tra cui:

  • XML con e senza prologo
  • Con e senza newline
  • Con e senza l'attributo "encoding =" nel prologo
  • Entrambi gli stili di nuova riga
  • Con e senza le informazioni di chunking presenti nel flusso HTTP

E ho provato la maggior parte di questi in più combinazioni in cui aveva senso che interagissero - niente! Sono alla fine del mio ingegno. Qualcuno ha mai visto un problema come questo prima che si spera possa far luce su di esso?

Grazie!


Probabilmente avremo bisogno di vedere altro codice. Un'altra possibilità è che localmente non venga suddiviso in blocchi mentre su GAE lo è. Come gestisci il codice prima di passarlo al parser?
Romain Hippeau

Ho considerato anche la possibilità di chunking, ma non sembra essere il caso poiché il messaggio di errore che il parser sta lanciando contiene l'intero XML proprio lì (è incollato sopra). L'intero codice SDK modificato può essere trovato su github.com/AdrianP/aws-sdk-for-java (guarda i commit più recenti) ma c'è MOLTO codice lì. Cercherò di creare presto un campione riproducibile più piccolo, anche se sarà difficile. È un software grande e complicato ... Grazie per il tuo feedback! :)
Adrian Petrescu


@ Raedwald, non credo che sia la mia domanda ad essere il duplicato, dato che la mia domanda è stata pubblicata un anno prima di quella :)
Adrian Petrescu

1
Questo dovrebbe essere un esempio di come dovrebbe essere posta una domanda su SO, leggerlo mi ha dato vari spunti su come eseguire il debug come sviluppatore (grazie OP)
Sudip Bhandari

Risposte:


129

La codifica nel tuo XML e XSD (o DTD) sono differenti.
Intestazione file XML: <?xml version='1.0' encoding='utf-8'?>
intestazione file XSD:<?xml version='1.0' encoding='utf-16'?>

Un altro possibile scenario che causa ciò è quando qualcosa viene prima della dichiarazione del tipo di documento XML. cioè potresti avere qualcosa di simile nel buffer:

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

o anche uno spazio o un carattere speciale.

Ci sono alcuni caratteri speciali chiamati marcatori dell'ordine dei byte che potrebbero essere nel buffer. Prima di passare il buffer al parser, fare questo ...

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

Ciao Romain, grazie per la risposta! Ho controllato due volte e tre volte più volte per qualsiasi cosa nel buffer prima del prologo (inclusi i caratteri nascosti) ma semplicemente non c'è nient'altro lì. Tuttavia, proverò il passaggio alla codifica utf-16: per curiosità, dove hai ottenuto le informazioni che l'XSD utilizza UTF-16?
Adrian Petrescu

@Adrian Petrescu Spiacenti, questi sono solo esempi Se stai usando DTD o XSD assicurati che corrispondano al tuo XML. Prima di analizzare l'XML, acquisiscilo in una stringa e racchiudilo con "|" e stampalo sulla console. Questo ti dirà se stai passando alcuni personaggi extra.
Romain Hippeau

Ah, capisco :) Purtroppo l'ho provato e non sembra essere il caso in questa situazione. Grazie comunque!
Adrian Petrescu

1
Grazie! Anche questo mi ha salvato. xml.trim () replaceFirst ( "^ ([\\ W] +) <", "<").;
stackoverflow

2
Qualcuno, per favore, faccia di questa la risposta accettata. Ho risolto subito il mio problema. Stavo analizzando un messaggio che iniziava con "Messaggio: <? Versione xml ...." Il problema era il testo prima del bit xml. Grazie :)
Ric Jafe

8

Questo messaggio di errore è sempre causato dal contenuto XML non valido nell'elemento iniziale. Ad esempio, punto extra piccolo "." all'inizio dell'elemento XML.

Qualsiasi carattere prima di " <?xml…." causerà il messaggio di errore " org.xml.sax.SAXParseException: contenuto non consentito nel prologo ".

Un piccolo punto “ . " prima di“<?xml….

Per risolverlo, elimina tutti quei personaggi strani prima del file “<?xml“.

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


3
Dovresti menzionare dove hai riferito che mkyong.com/java/sax-error-content-is-not-allowed-in-prolog
arulraj.net

5

Stavo affrontando lo stesso problema. Nel mio caso i file XML sono stati generati dal programma c # e inseriti in AS400 per ulteriori elaborazioni. Dopo alcune analisi ho scoperto che stavo usando la codifica UTF8 durante la generazione di file XML mentre javac (in AS400) utilizza "UTF8 senza BOM". Quindi, ho dovuto scrivere codice aggiuntivo simile a quello menzionato di seguito:

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

Ho avuto problemi durante l'ispezione del file xml in Notepad ++ e il salvataggio del file, anche se avevo il tag xml utf-8 superiore come <?xml version="1.0" encoding="utf-8"?>

È stato risolto salvando il file in notpad ++ con Codifica (Tab)> Codifica in UTF-8: selezionato (era Codifica in UTF-8-BOM)


3

La rimozione della dichiarazione xml lo ha risolto

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

2

Nel mio file xml, l'intestazione aveva questo aspetto:

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

In un file di prova, stavo leggendo i byte del file e decodificando i dati come UTF-8 (non realizzando che l'intestazione in questo file era utf-16) per creare una stringa.

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

Quando ho provato a deserializzare questa stringa in un oggetto, vedevo lo stesso errore:

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

Quando ho aggiornato la seconda riga in

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

Sono riuscito a deserializzare l'oggetto senza problemi. Quindi, come Romain aveva notato sopra, le codifiche devono corrispondere.


1

Stavo affrontando lo stesso problema chiamato "Il contenuto non è consentito nel prologo" nel mio file xml.

Soluzione

Inizialmente la mia cartella principale era "# Filename ".

Quando ho rimosso il primo carattere "#", l'errore è stato risolto.

Non c'è bisogno di rimuovere il #filename ... Prova in questo modo ..

Invece di passare un oggetto File o URL al metodo unmarshaller, usa un FileInputStream.

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

1

Motivo imprevisto: #carattere nel percorso del file

A causa di alcuni bug interni, l'errore Contenuto non consentito nel prologo viene visualizzato anche se il contenuto del file stesso è corretto al 100% ma si sta fornendo il nome del file come C:\Data\#22\file.xml.

Questo potrebbe valere anche per altri caratteri speciali.

Come verificare: se sposti il ​​file in un percorso senza caratteri speciali e l'errore scompare, si trattava di questo problema.


1

Oggi ho ricevuto lo stesso messaggio di errore. La soluzione era cambiare il documento da UTF-8 con BOM a UTF-8 senza BOM


Ho avuto lo stesso problema. La modifica del formato del file ha risolto il problema. Grazie!
code_fish

0

Avevo un carattere di tabulazione invece degli spazi. La sostituzione della scheda "\ t" ha risolto il problema.

Taglia e incolla l'intero documento in un editor come Notepad ++ e visualizza tutti i caratteri.


0

Nel mio caso del problema, la soluzione era sostituire le dieresi tedesche (äöü) con i loro equivalenti HTML ...


0

sotto sono la causa sopra "org.xml.sax.SAXParseException: il contenuto non è consentito nel prologo".

  1. Per prima cosa controlla il percorso del file schema.xsd e file.xml.
  2. La codifica nel tuo XML e XSD (o DTD) dovrebbe essere la stessa.
    Intestazione file XML: <?xml version='1.0' encoding='utf-8'?>
    intestazione file XSD:<?xml version='1.0' encoding='utf-8'?>
  3. se qualcosa viene prima della dichiarazione del tipo di documento XML.ie: hello<?xml version='1.0' encoding='utf-16'?>

0

Nello spirito di "elimina tutti quegli strani caratteri prima di <? Xml", ecco il mio codice Java, che funziona bene con l'input tramite un 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, i byte che stavo vedendo sono (in decimale): 239, 187, 191.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.