2010-06-13 19 views
60

He estado golpeando mi cabeza contra este error absolutamente exasperante durante las últimas 48 horas, así que pensé que finalmente tiraría la toalla y trataría de preguntar aquí antes de tirar mi computadora portátil por la ventana."El contenido no está permitido en prolog" al analizar XML perfectamente válido en GAE

Estoy tratando de analizar el XML de respuesta de una llamada que realicé a AWS SimpleDB. La respuesta está volviendo al hilo bien; por ejemplo, puede verse como:

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

que pase en este XML a un analizador con

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

y llamo eventReader.nextEvent(); un montón de veces para obtener los datos que quiero.

Aquí está la parte extraña: funciona genial dentro del servidor local. La respuesta viene, lo analizo, todos están felices. El problema es que cuando puedo implementar el código de Google App Engine, la petición de salida sigue funcionando, y la respuesta XML parece idéntica al 100% y correcta para mí, pero la respuesta no puede analizar con la siguiente excepción:

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) 

Compruebo doble, triple y cuádruple este XML para caracteres "invisibles" o no codificados en UTF8, etc. Lo miré byte a byte en una matriz para marcas de orden de bytes o algo de esa naturaleza. Nada; pasa todas las pruebas de validación que pude lanzar. Aún más extraño, sucede si uso un analizador basado en Saxon también, pero SOLAMENTE en GAE, siempre funciona bien en mi entorno local.

Hace que sea muy difícil rastrear el código de problemas cuando solo puedo ejecutar el depurador en un entorno que funciona a la perfección (no he encontrado una buena manera de depurar de forma remota en GAE). Sin embargo, el uso de los medios primitivos que tengo, lo he intentado un millón de enfoques, incluyendo:

  • XML con y sin el prólogo
  • Con y sin saltos de línea
  • con y sin el "encoding =" atributo en el prólogo
  • Ambos estilos de nueva línea
  • con y sin la información de fragmentación presente en la corriente de HTTP

y no tengo intenté la mayoría de estos en múltiples combinaciones donde tenía sentido que interactuaran, ¡nada! Estoy al final de mi ingenio. ¿Alguien ha visto un problema como este antes de que pueda arrojar algo de luz sobre él?

Gracias!

+0

Probablemente vamos a necesitar ver más código. Otra posibilidad es que a nivel local no se fragmente mientras está en GAE. ¿Cómo maneja el código antes de pasarlo al analizador? –

+0

Consideré la posibilidad de fragmentación también, pero no parece ser el caso dado que el mensaje de error que arroja el analizador contiene el XML completo allí mismo (está pegado arriba). El código completo SDK modificado se puede encontrar en http://github.com/AdrianP/aws-sdk-for-java (vea los commits más recientes) pero hay MUCHO código allí. Trataré de crear pronto una muestra reproducible más pequeña, aunque incluso eso será difícil. Es una gran pieza de software complicada ... ¡Gracias por tus comentarios! :) –

+0

posible duplicado de [org.xml.sax.SAXParseException: el contenido no está permitido en prolog] (http://stackoverflow.com/questions/5138696/org-xml-sax-saxparseexception-content-is-not-allowed -en-prólogo) – Raedwald

Respuesta

80

La codificación en su XML y XSD (o DTD) son diferentes.
encabezado del archivo XML: <?xml version='1.0' encoding='utf-8'?>
XSD encabezado del archivo: <?xml version='1.0' encoding='utf-16'?>

Otro posible escenario que causa esto es cuando surge algo antes de la declaración de tipo de documento XML. es decir, podría tener algo como esto en el búfer:

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

o incluso un espacio o un carácter especial.

Hay algunos caracteres especiales llamados marcadores de orden de bytes que podrían estar en el búfer. antes de pasar el búfer en el analizador hacer esto ...

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

Hola Romain, gracias por la respuesta! He revisado el doble y el triple muchas veces para ver si hay algo en el búfer antes del prólogo (incluidos los caracteres ocultos), pero simplemente no hay nada más allí. Sin embargo, le doy la oportunidad de cambiar a codificación de UTF-16. Por curiosidad, ¿de dónde sacó la información de que el XSD usa UTF-16? –

+0

@Adrian Petrescu Lo sentimos, estos son solo ejemplos Si está utilizando DTD o XSD asegúrese de que coincidan con su XML. Antes de analizar la captura XML en una Cadena y rodearla con '|' e imprímalo en la consola. Esto te dirá si estás pasando algunos caracteres adicionales. –

+0

Ah, ya veo :) Desafortunadamente lo probé y no parece ser el caso en esta situación. ¡Gracias de cualquier manera! –

5

Este mensaje de error es siempre causada por el contenido XML válido en el elemento inicial. Por ejemplo, un pequeño punto "." Al principio del elemento XML.

Cualquier caracteres antes del “<?xml….” hará más arriba “org.xml.sax.SAXParseException: contenido no está permitido en el prólogo” mensaje de error.

Un pequeño punto ". "antes de “<?xml….

Para solucionarlo, simplemente borre todos esos caracteres extraños antes del “<?xml“.

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

+2

Debe mencionar a dónde se refiere que http://www.mkyong.com/java/sax-error-content-is-not-allowed-in-prolog/ –

0

que tenían un carácter de tabulación en lugar de espacios. Reemplazar la pestaña '\ t' solucionó el problema.

Corte y pegue todo el documento en un editor como Notepad ++ y muestre todos los caracteres.

2

Estaba enfrentando el mismo problema. En mi caso, los archivos XML se generaron a partir del programa C# y se introdujeron en AS400 para su posterior procesamiento. Después de algunos análisis identifiqué que estaba usando la codificación UTF8 mientras generaba archivos XML mientras que javac (en AS400) usa "UTF8 sin BOM". Por lo tanto, tenía que escribir código adicional similar a la mencionada a continuación:

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

que estaba enfrentando el mismo problema que se llama "contenido no está permitido en el prólogo" en mi archivo XML.

Solución

principio mi carpeta raíz era '# Nombre'.

Cuando eliminé el primer carácter '#', se resolvió el error.

No hay necesidad de quitar el #filename ... Trate de esta manera ..

En lugar de pasar de un archivo o un objeto URL para el método unmarshaller, use un FileInputStream.

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

En mi archivo XML, la cabecera era la siguiente:

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

En un archivo de prueba, estaba leyendo los bytes del archivo y la decodificación de los datos como UTF-8 (sin darse cuenta de la cabecera en este archivo fue utf-16) para crear una cadena.

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

Cuando traté de deserializar esta cadena en un objeto, que estaba viendo el mismo error:

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

Cuando he actualizado la segunda línea de

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

pude deserializar el objeto muy bien. Entonces, como señaló Romain arriba, las codificaciones deben coincidir.

0

En mi ejemplo del problema, la solución fue reemplazar las diéresis alemanas (AOU) con sus equivalentes HTML ...

0

abajo son la causa más arriba “org.xml.sax.SAXParseException: contenido no está permitido en prólogo "excepción.

  1. Primero compruebe la ruta del archivo de schema.xsd y file.xml.
  2. La codificación en su XML y XSD (o DTD) debe ser la misma.
    encabezado del archivo XML: <?xml version='1.0' encoding='utf-8'?>
    XSD encabezado del archivo: <?xml version='1.0' encoding='utf-8'?>
  3. si algo viene antes de que el tipo de documento XML declaration.i.e: hello<?xml version='1.0' encoding='utf-16'?>
0

En mi caso, tuve el problema con un archivo build.xml. Esto fue resuelto con solo ir al Build > Clean Project.

Cuestiones relacionadas