java - "El contenido no está permitido en prolog" al analizar XML perfectamente válido en GAE
google-app-engine parsing (10)
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.
Estoy tratando de analizar el XML de respuesta de una llamada que hice a AWS SimpleDB. La respuesta está volviendo al hilo bien; por ejemplo, puede verse así:
<?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>
Paso este XML a un analizador con
XMLEventReader eventReader = xmlInputFactory.createXMLEventReader(response.getContent());
y llama a 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 implemento el código en Google App Engine, la solicitud saliente sigue funcionando, y el XML de respuesta parece 100% idéntico y correcto para mí, pero la respuesta no se 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 busqué byte a byte en una matriz para byte-order-marks 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, utilizando los medios primitivos que tengo, he intentado un millón de enfoques que incluyen:
- XML con y sin el prólogo
- Con y sin nuevas líneas
- Con y sin el atributo "encoding =" en el prólogo
- Ambos estilos de nueva línea
- Con y sin la información fragmentada presente en la secuencia HTTP
Y he probado la mayoría de estos en múltiples combinaciones donde tiene sentido que interactúen, ¡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!
En el espíritu de "simplemente elimine todos esos caracteres extraños antes del <? Xml", aquí está mi código Java, que funciona bien con la entrada a través de 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, los bytes que estaba viendo son (en decimal): 239, 187, 191.
En mi archivo xml, el encabezado se veía así:
<?xml version="1.0" encoding="utf-16"? />
En un archivo de prueba, estaba leyendo los bytes del archivo y decodificando los datos como UTF-8 (sin darme cuenta de que el encabezado en este archivo era utf-16) para crear una cadena.
byte[] data = Files.readAllBytes(Paths.get(path));
String dataString = new String(data, "UTF-8");
Cuando intenté deserializar esta cadena en un objeto, estaba viendo el mismo error:
javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,1]
Message: Content is not allowed in prolog.
Cuando actualicé la segunda línea para
String dataString = new String(data, "UTF-16");
Pude deserializar el objeto muy bien. Entonces, como señaló Romain arriba, las codificaciones deben coincidir.
En mi caso, tuve el problema con un archivo build.xml
. Esto se solucionó con solo ir a Build > Clean Project
.
En mi instancia del problema, la solución fue reemplazar las diéresis alemanas (äöü) con sus equivalentes HTML ...
Estaba enfrentando el mismo problema llamado "El contenido no está permitido en prolog" en mi archivo xml.
Solución
Inicialmente, mi carpeta raíz era ''# Nombre de archivo ''.
Cuando eliminé el primer carácter ''#'', el error se resolvió.
No es necesario eliminar el # nombre de archivo ... Inténtalo de esta manera ...
En lugar de pasar un archivo o un objeto URL al método unmarshaller, use un FileInputStream.
File myFile = new File("........");
Object obj = unmarshaller.unmarshal(new FileInputStream(myFile));
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, tuvo que escribir un código adicional similar al mencionado 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
Este mensaje de error siempre es causado por el contenido XML no válido en el elemento inicial. Por ejemplo, un pequeño punto "." Al principio del elemento XML.
Cualquier carácter antes del " <?xml….
" Causará el mensaje de error" org.xml.sax.SAXParseException: Content no se permite en prolog ".
Un pequeño punto " . "Antes del “<?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/
La codificación en su XML y XSD (o DTD) son diferentes.
Cabecera del archivo XML: <?xml version=''1.0'' encoding=''utf-8''?>
Cabecera del archivo XSD: <?xml version=''1.0'' encoding=''utf-16''?>
Otro escenario posible que causa esto es cuando algo viene antes de la declaración del tipo de documento XML. es decir, puede tener algo como esto en el búfer:
helloworld<?xml version="1.0" encoding="utf-8"?>
o incluso un espacio o personaje 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 al Analizador, haga esto ...
String xml = "<?xml ...";
xml = xml.trim().replaceFirst("^([//W]+)<","<");
Tenía 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.
a continuación se muestran las causas anteriores a la excepción "org.xml.sax.SAXParseException: el contenido no está permitido en prolog".
- Primero compruebe la ruta del archivo de schema.xsd y file.xml.
- La codificación en su XML y XSD (o DTD) debe ser la misma.
Cabecera del archivo XML:<?xml version=''1.0'' encoding=''utf-8''?>
Cabecera del archivo XSD:<?xml version=''1.0'' encoding=''utf-8''?>
- si algo viene antes del tipo de documento XML declaration.ie:
hello<?xml version=''1.0'' encoding=''utf-16''?>