web-dev-qa-db-fra.com

"Le contenu n'est pas autorisé dans prolog" lors de l'analyse d'un code XML parfaitement valide sur GAE

Je bats la tête contre cet insecte absolument exaspérant depuis 48 heures, alors je pensais enfin jeter l'éponge et essayer de poser la question avant de jeter mon ordinateur portable par la fenêtre.

J'essaie d'analyser la réponse XML à partir d'un appel que j'ai effectué vers AWS SimpleDB. La réponse revient très bien sur le fil; par exemple, cela peut ressembler à:

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

Je passe ce XML à un analyseur avec 

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

et appelez eventReader.nextEvent(); plusieurs fois pour obtenir les données que je veux.

Voici la partie bizarre - cela fonctionne très bien à l'intérieur du serveur local. La réponse arrive, je l'analyse, tout le monde est content. Le problème est que, lorsque je déploie le code dans Google App Engine, la demande sortante fonctionne toujours et que le XML de réponse semble être identique et correct à 100%, mais l'analyse ne parvient pas à l'analyse avec l'exception suivante:

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)

J'ai double, triple, quadruple vérifié ce XML pour des «caractères invisibles» ou des caractères encodés non UTF8, etc. Je l'ai examiné octet par octet dans un tableau pour rechercher des marques d'ordre des octets ou quelque chose de ce genre. Rien; il passe tous les tests de validation possibles. Encore plus étrange, cela se produit si j'utilise également un analyseur basé sur Saxon - mais UNIQUEMENT sur GAE, cela fonctionne toujours bien dans mon environnement local.

Il est très difficile de rechercher les problèmes dans le code lorsque je ne peux exécuter le débogueur que sur un environnement qui fonctionne parfaitement (je n'ai pas trouvé de moyen de déboguer à distance sur GAE). Néanmoins, en utilisant les moyens primitifs dont je dispose, j'ai essayé plusieurs millions d'approches, notamment:

  • XML avec et sans le prologue
  • Avec et sans nouvelles lignes
  • Avec et sans l'attribut "encoding =" dans le prologue
  • Les deux styles de nouvelle ligne
  • Avec et sans les informations de segmentation présentes dans le flux HTTP

Et j'ai essayé la plupart de ces combinaisons dans de multiples combinaisons où il était logique qu'elles interagissent - rien! Je suis à bout de forces. Quelqu'un a-t-il déjà vu un problème comme celui-ci qui, espérons-le, pourrait nous éclairer?

Merci!

75
Adrian Petrescu

Le codage dans votre XML et XSD (ou DTD) est différent.
En-tête de fichier XML: <?xml version='1.0' encoding='utf-8'?>
En-tête du fichier XSD: <?xml version='1.0' encoding='utf-16'?>

Un autre scénario possible qui en est la cause est que quelque chose arrive avant la déclaration du type de document XML. c'est-à-dire que vous pourriez avoir quelque chose comme ceci dans le tampon: 

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

ou même un espace ou un caractère spécial.

Il existe des caractères spéciaux appelés marqueurs d'ordre d'octet qui pourraient se trouver dans la mémoire tampon . 

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

Ce message d'erreur est toujours causé par le contenu XML non valide dans l'élément de début. Par exemple, un très petit point «.» Au début de l'élément XML.

Tous les caractères précédant “<?xml….” provoqueront le message d'erreur “org.xml.sax.SAXParseException: Le contenu n'est pas autorisé dans prolog”.

Un petit point “. ”Avant le “<?xml….

Pour résoudre ce problème, supprimez tous ces caractères étranges avant le “<?xml“.

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

7
Sunmit Girme

Je faisais face au même problème. Dans mon cas, les fichiers XML ont été générés à partir du programme c # et transmis à AS400 pour traitement ultérieur. Après une analyse, j'ai constaté que j'utilisais le codage UTF8 lors de la génération de fichiers XML alors que javac (sous AS400) utilise "UTF8 sans BOM". Il a donc fallu écrire du code supplémentaire semblable à celui mentionné ci-dessous:

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

Supprimer la déclaration XML résolue

<?xml version='1.0' encoding='utf-8'?>
4
F.O.O

Dans mon fichier XML, l'en-tête ressemblait à ceci: 

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

Dans un fichier de test, je lisais les octets du fichier et décodais les données au format UTF-8 (la non-réalisation de l'en-tête dans ce fichier était utf-16) pour créer une chaîne.

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

Quand j'ai essayé de désérialiser cette chaîne en un objet, je voyais la même erreur:

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

Quand j'ai mis à jour la deuxième ligne à

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

J'ai pu désérialiser l'objet parfaitement. Comme Romain l’a noté plus haut, les codages doivent être identiques.

2
dfritch

Je faisais face au même problème appelé "Le contenu n'est pas autorisé dans prolog" dans mon fichier XML.

Solution

Au départ, mon dossier racine était '# Nom du fichier '.

Quand j'ai enlevé le premier caractère '#', l'erreur a été résolue.

Pas besoin de supprimer le #filename ... Essayez de cette façon .. 

Au lieu de transmettre un objet File ou URL à la méthode unmarshaller, utilisez un FileInputStream.

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

J'ai eu un problème lors de l'inspection du fichier XML dans Notepad ++ et de l'enregistrement du fichier, même si j'avais la balise XML utf-8 supérieure en tant que <?xml version="1.0" encoding="utf-8"?>

A été corrigé en enregistrant le fichier dans notpad ++ avec Encodage (Tabulation)> Encoder dans UTF-8: sélectionné (était Encoder dans UTF-8-BOM)

2
techloris_109

Dans mon exemple du problème, la solution consistait à remplacer les lettres allemandes (äöü) par leurs équivalents HTML ...

0
MBaas

Dans l'esprit de "supprimez tous ces caractères étranges avant le <? Xml", voici mon code Java, qui fonctionne bien avec une entrée via 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, les octets que je voyais sont (en décimal): 239, 187, 191.

0
Tamias

Dans mon cas, j'ai eu le problème avec un fichier build.xml. Cela a été résolu en allant simplement à Build > Clean Project.

0
Muz

les causes ci-dessous sont la cause ci-dessus «org.xml.sax.SAXParseException: le contenu n'est pas autorisé dans prolog».

  1. Commencez par vérifier le chemin du fichier schema.xsd et file.xml.
  2. Le codage dans votre XML et XSD (ou DTD) doit être identique.
    En-tête de fichier XML: <?xml version='1.0' encoding='utf-8'?>
    En-tête du fichier XSD: <?xml version='1.0' encoding='utf-8'?>
  3. si quelque chose précède le type de document XML declaration.i.e: hello<?xml version='1.0' encoding='utf-16'?>
0
Avinash Dubey

Raison inattendue: # caractère dans le chemin du fichier

En raison d'un bogue interne, l'erreur Content n'est pas autorisé dans prolog} apparaît également si le contenu du fichier est correct à 100% mais que vous fournissez le nom du fichier comme C:\Data\#22\file.xml.

Cela peut éventuellement s'appliquer à d'autres caractères spéciaux.

Comment vérifier: Si vous déplacez votre fichier dans un chemin sans caractères spéciaux et que l'erreur disparaît, c'est ce problème-là.

0
miroxlav

J'avais un caractère de tabulation au lieu d'espaces ... Le remplacement de l'onglet '\ t' a résolu le problème.

Coupez et collez le document dans un éditeur tel que Notepad ++ et affichez tous les caractères.

0
SoloPilot