org.xml.sax.SAXParseException: o conteúdo não é permitido no prólogo

161

Eu tenho um cliente de serviço web baseado em Java conectado ao serviço web Java (implementado na estrutura Axis1).

Estou recebendo a seguinte exceção no meu arquivo de log:

Caused by: org.xml.sax.SAXParseException: Content is not allowed in prolog.
    at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
    at org.apache.xerces.util.ErrorHandlerWrapper.fatalError(Unknown Source)
    at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
    at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
    at org.apache.xerces.impl.XMLScanner.reportFatalError(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentScannerImpl$PrologDispatcher.dispatch(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
    at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
    at javax.xml.parsers.SAXParser.parse(Unknown Source)
    at org.apache.axis.encoding.DeserializationContext.parse(DeserializationContext.java:227)
    at org.apache.axis.SOAPPart.getAsSOAPEnvelope(SOAPPart.java:696)
    at org.apache.axis.Message.getSOAPEnvelope(Message.java:435)
    at org.apache.ws.axis.security.WSDoAllReceiver.invoke(WSDoAllReceiver.java:114)
    at org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:32)
    at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
    at org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
    at org.apache.axis.client.AxisClient.invoke(AxisClient.java:198)
    at org.apache.axis.client.Call.invokeEngine(Call.java:2784)
    at org.apache.axis.client.Call.invoke(Call.java:2767)
    at org.apache.axis.client.Call.invoke(Call.java:2443)
    at org.apache.axis.client.Call.invoke(Call.java:2366)
    at org.apache.axis.client.Call.invoke(Call.java:1812)
ag112
fonte
11
Ajudaria se você nos mostrasse o XML que está tentando analisar. (Apenas as primeiras linhas faria, eu espero.)
Stephen C
Obrigado Stephen, estou tentando recuperar a solicitação XML da estrutura do AXIS e colá-la aqui. Portanto, o entendimento geral do erro acima é que XML não está bem formado.
Ag112 28/02
Eu tive esse problema porque estava tentando transformar o nome da string do arquivo xml em vez do arquivo xml como uma string! : P
Gaʀʀʏ 16/05

Respostas:

242

Isso geralmente é causado por um espaço em branco antes da declaração XML, mas pode ser qualquer texto , como um traço ou qualquer caractere. Eu digo muitas vezes causado pelo espaço em branco porque as pessoas assumem que o espaço em branco é sempre ignorável, mas esse não é o caso aqui.


Outra coisa que costuma acontecer é uma UTF-8 BOM (marca de ordem de bytes), que é permitida antes que a declaração XML possa ser tratada como espaço em branco se o documento for entregue como um fluxo de caracteres para um analisador XML em vez de um fluxo de bytes .

O mesmo pode acontecer se os arquivos de esquema (.xsd) forem usados ​​para validar o arquivo xml e um dos arquivos de esquema tiver uma BOM UTF-8 .

Mike Sokolov
fonte
17
Para todos como eu, que luta para entender o que fazer com John Humphreys - sugestão de w00te: mudar Document document = documentBuilder.parse(new InputSource(new StringReader(xml)))paraDocument document = documentBuilder.parse(new InputSource(new ByteArrayInputStream(xml.getBytes("UTF-8"))))
RealMan
32

Na verdade, além do post de Yuriy Zubarev

Quando você passa um arquivo xml inexistente para o analisador. Por exemplo, você passa

new File("C:/temp/abc")

quando apenas o arquivo C: /temp/abc.xml existe no seu sistema de arquivos

Em ambos os casos

builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
document = builder.parse(new File("C:/temp/abc"));

ou

DOMParser parser = new DOMParser();
parser.parse("file:C:/temp/abc");

Todos dão a mesma mensagem de erro.

Bug muito decepcionante, porque o seguinte rastreamento

javax.servlet.ServletException
    at org.apache.xerces.parsers.DOMParser.parse(Unknown Source)
...
Caused by: org.xml.sax.SAXParseException: Content is not allowed in prolog.
... 40 more

não diz nada sobre o fato de 'o nome do arquivo estar incorreto' ou 'esse arquivo não existe'. No meu caso, eu tinha o arquivo xml absolutamente correto e tive que passar 2 dias para determinar o problema real.

Egor
fonte
O mesmo com a tentativa de analisar um diretório em vez de um nome de arquivo, FWIW.
Rogerdpack
... @ Egor é por isso que todo mundo odeia XML. Perder 2 dias de trabalho para um fracasso tão estúpida ..
Gewure
Concordo absolutamente @Gewure :) Isso foi algum post antigo a partir de 2012 e até me esqueço sobre isso, mas é verdade
Egor
1
Isso também acontece quando você tem um caminho correto, mas com símbolos especiais, como: C: \ # MyFolder \ My.XML O arquivo existe, mas o "#" traz problema ao analisador XML ... o próprio Java, assim como M $ do Windows, não tem nenhum problema com este nome de pasta .... comportamento mensagem de exceção Very bad ....
Alex
26

Tente adicionar um espaço entre a encoding="UTF-8"string no prólogo e a terminação ?>. No XML, o prólogo designa esse elemento delimitado por ponto de interrogação entre colchetes no início do documento (enquanto o prólogo da tag no fluxo de empilhamento se refere à linguagem de programação).

Adicionado: esse traço na frente do seu prólogo faz parte do documento? Esse seria o erro lá, ter dados na frente do prólogo -<?xml version="1.0" encoding="UTF-8"?>,.

hardmath
fonte
1
+1. Descobri que alguns analisadores XML excluem essa exceção mesmo quando o prólogo XML contém espaços - então acho que definitivamente vale a pena verificar se nada precede o <?xml ver...bit.
11

Eu tive o mesmo problema (e resolvi) ao tentar analisar um documento XML com o freemarker.

Eu não tinha espaços antes do cabeçalho do arquivo XML.

O problema ocorre quando e somente quando a codificação do arquivo e o atributo de codificação XML são diferentes. (ex: arquivo UTF-8 com atributo UTF-16 no cabeçalho).

Então, eu tinha duas maneiras de resolver o problema:

  1. alterando a codificação do próprio arquivo
  2. alterando o cabeçalho UTF-16 para UTF-8
JoshDM
fonte
1
Eu acho que, em geral, qualquer caso em que o analisador receba informações conflitantes sobre a codificação de caracteres pode causar esse problema.
Raedwald
9

Isso significa que o XML está malformado ou o corpo da resposta não é um documento XML.

Yuriy Zubarev
fonte
Eu verifiquei e parece que o XML está bem formado. Aqui está o instantâneo: - <? Xml version = "1.0" encoding = "UTF-8"?> <Soapenv: xmlns de envelope: soapenv = " schemas.xmlsoap.org/soap/envelope " xmlns: xsd = " w3.org/ 2001 / XMLSchema "xmlns: xsi =" w3.org/2001/XMLSchema-instance "> <soapenv: Cabeçalho> <wsse: Segurança xmlns: wsse =" docs.oasis-open.org/wss/2004/01/… " soapenv: mustUnderstand = "1"> .... </ wsse: Security> </ soapenv: Header> <soapenv: Body> .XX .. </ soapenv: Body> </ soapenv: Envelope>
ag112
1
Sim, se houver um traço na frente, ele quebraria o XML.
Yuriy Zubarev 28/02
7

Passei apenas 4 horas rastreando um problema semelhante em um WSDL. Acontece que o WSDL usou um XSD que importa outro namespace XSD. Este XSD importado continha o seguinte:

<?xml version="1.0" encoding="UTF-8"?>
<schema targetNamespace="http://www.xyz.com/Services/CommonTypes" elementFormDefault="qualified"
    xmlns="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:CommonTypes="http://www.xyz.com/Services/CommonTypes">

 <include schemaLocation=""></include>  
    <complexType name="RequestType">
        <....

Observe o vazio include elemento ! Esta foi a raiz dos meus problemas. Eu acho que esta é uma variação no arquivo do Egor não encontrado problema acima.

+1 a um relatório de erro decepcionante.

colin_froggatt
fonte
4

No meu caso, remover completamente o atributo 'encoding = "UTF-8"' funcionou.

Parece um problema de codificação do conjunto de caracteres, talvez porque seu arquivo não esteja realmente em UTF-8.

Jerome Louvel
fonte
4

Minha resposta provavelmente não ajudaria você, mas ajudaria nesse problema em geral.

Quando você vir esse tipo de exceção, tente abrir o arquivo xml em qualquer editor hexadecimal e, em algum momento, poderá ver bytes adicionais no início do arquivo que o editor de texto não mostra.

Exclua-os e seu xml será analisado.

Igor Kustov
fonte
4

Às vezes é o código, não o XML

O código a seguir,

Document doc = dBuilder.parse(new InputSource(new StringReader("file.xml")));

também resultará nesse erro,

[Erro fatal]: 1: 1: o conteúdo não é permitido em prolog.org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; O conteúdo não é permitido no prólogo.

porque está tentando analisar a string literal "file.xml"(e não o conteúdo do file.xmlarquivo) e falhando porque"file.xml" como uma string, não é um XML bem formado.

Correção: Remover StringReader():

Document doc = dBuilder.parse(new InputSource("file.xml"));

Da mesma forma, problemas com buffer sujo podem deixar lixo residual à frente do XML real. Se você verificou cuidadosamente seu XML e ainda está recebendo esse erro, registre o conteúdo exato que está sendo passado para o analisador; Às vezes, o que realmente está sendo analisado é surpreendente.

kjhughes
fonte
1
Esta solução guiou no caminho certo, pois eu esqueci de adicionar o applicaionContext.xmlcaminho no código e não estava verificando o código estava procurando erro apenas no arquivo XML
Mrinmoy
3

Primeiro limpe o projeto e depois reconstrua o projeto. Eu também estava enfrentando o mesmo problema. Tudo veio bem depois disso.

Bibin Johny
fonte
2

Se tudo mais falhar, abra o arquivo em binário para garantir que não haja caracteres engraçados [3 caracteres não imprimíveis no início do arquivo que identifiquem o arquivo como utf-8] no início do arquivo. Fizemos isso e encontramos alguns. então convertemos o arquivo de utf-8 para ascii e funcionou.

Ralph
fonte
2

Para os mesmos problemas, removi a seguinte linha,

  File file = new File("c:\\file.xml");
  InputStream inputStream= new FileInputStream(file);
  Reader reader = new InputStreamReader(inputStream,"UTF-8");
  InputSource is = new InputSource(reader);
  is.setEncoding("UTF-8");

Está funcionando bem. Não sei ao certo por que esse UTF-8 dá problema. Para me manter em choque, também funciona bem para o UTF-8.

Estou usando o Windows 7 de 32 bits e o Netbeans IDE com Java * jdk1.6.0_13 *. Não faço ideia de como isso funciona.

Dineshkumar Ponnusamy
fonte
2

Como Mike Sokolov já apontou, uma das possíveis razões é a presença de alguns caracteres (como um espaço em branco) antes da tag.

Se seu XML de entrada estiver sendo lido como uma String (em oposição à matriz de bytes), você poderá substituir sua string de entrada pelo código abaixo para garantir que todos os caracteres 'desnecessários' antes da tag xml sejam apagados.

inputXML=inputXML.substring(inputXML.indexOf("<?xml"));

Você precisa ter certeza de que o xml de entrada começa com a tag xml.

Sahil J
fonte
2

No meu caso, o web.xml no meu aplicativo tem espaço extra, mesmo depois que eu excluí não funcionava, eu tinha que reverter chages e suas correções e sim, eu estava brincando com logging.properties e web.xml no meu tomcat, mas mesmo depois de reverter o erro continuava sendo exibido, então isso foi corrigido)).

espaço extra

Para ser específico, tentei adicionar org.apache.catalina.filters.ExpiresFilter.level = FINE stack over flow algo sobre logging.properties

shareef
fonte
1

Segui as instruções encontradas aqui e recebi o mesmo erro.

Tentei várias coisas para resolvê-lo (ou seja, alterar a codificação, digitar o arquivo XML em vez de copiar e colar) no Bloco de notas e no Bloco de notas XML, mas nada funcionou.

O problema foi resolvido quando editei e salvei meu arquivo XML no Notepad ++ (codificação -> utf-8 sem BOM)

BitCollector
fonte
1

Para todos aqueles que recebem esse erro: AVISO: Catalina.start usando conf / server.xml: o conteúdo não é permitido no prólogo.

Não é muito informativo .. mas o que isso realmente significa é que há lixo no seu arquivo conf / server.xml.

Eu já vi esse erro exato em outros arquivos XML. Esse erro pode ser causado por alterações em um editor de texto que introduz o lixo.

A maneira de verificar se você tem lixo no arquivo ou não é abri-lo com um "Editor HEX". Se você vir algum caractere antes dessa string

     "<?xml version="1.0" encoding="UTF-8"?>"

assim seria lixo

     "‰ŠŒ<?xml version="1.0" encoding="UTF-8"?>"

esse é o seu problema .... A solução é usar um bom editor HEX. Um que permita salvar arquivos com diferentes tipos de codificação.

Em seguida, salve-o como UTF-8. Alguns sistemas que usam arquivos XML podem precisar salvá-lo como UTF NO BOM, o que significa com "NO Byte Order Mark"

Espero que isto seja útil a alguém!!

CA Martin
fonte
1

Para mim, um Build-> Clean corrigiu tudo!

FabioLux
fonte
1

Para corrigir o problema de lista técnica nos sistemas Unix / Linux:

  1. Verifique se há um caractere de lista técnica indesejado: hexdump -C myfile.xml | more um caractere de lista técnica indesejado aparecerá no início do arquivo como...<?xml>

  2. Como alternativa, faça file myfile.xml. Um arquivo com um caractere de lista técnica aparecerá como:myfile.xml: XML 1.0 document text, UTF-8 Unicode (with BOM) text

  3. Corrija um único arquivo com: tail -c +4 myfile.xml > temp.xml && mv temp.xml myfile.xml

  4. Repita 1 ou 2 para verificar se o arquivo foi limpo. Provavelmente também é sensato fazer view myfile.xmlpara verificar o conteúdo permaneceu.

Aqui está um script bash para higienizar uma pasta inteira de arquivos XML:

#!/usr/bin/env bash

# This script is to sanitise XML files to remove any BOM characters

has_bom() { head -c3 "$1" | LC_ALL=C grep -qe '\xef\xbb\xbf'; }

for filename in *.xml ; do
  if has_bom ${filename}; then
    tail -c +4 ${filename} > temp.xml
    mv temp.xml ${filename}
  fi
done
Lydia Ralph
fonte
0

Apenas um pensamento adicional sobre este para o futuro. Para obter esse bug, pode-se simplesmente pressionar a tecla delete ou alguma outra tecla aleatoriamente quando eles têm uma janela XML como a exibição ativa e não estão prestando atenção. Isso já aconteceu comigo antes com o arquivo struts.xml no meu aplicativo da web. Cotovelos desajeitados ...

demongolem
fonte
Certifiquei-me de não pressionar nenhuma tecla #
Mad-D
0

Eu também estava recebendo o mesmo

XML reader error: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,2] Message: Reference is not allowed in prolog.

, quando meu aplicativo estava criando uma resposta XML para uma chamada RestFull Webservice. Ao criar o formato XML String, substituí o & lt e & gt por <e> e o erro foi disparado, e eu estava obtendo uma resposta adequada. Não tenho certeza de como funcionou, mas funcionou.

amostra :

String body = "<ns:addNumbersResponse xmlns:ns=\"http://java.duke.org\"><ns:return>"
            +sum
            +"</ns:return></ns:addNumbersResponse>";
Satish M
fonte
0

Eu tive o mesmo problema.

Primeiro, baixei o arquivo XML para a área de trabalho local e recebi Content is not allowed in prologdurante o arquivo de importação no servidor de portal. Até o arquivo visual estava bom para mim, mas de alguma forma estava corrompido.

Então, baixei novamente o mesmo arquivo, tentei o mesmo e funcionou.

paresh
fonte
0

Tivemos o mesmo problema recentemente e acabou sendo o caso de uma URL incorreta e, consequentemente, de uma resposta HTTP 403 padrão (que obviamente não é o XML válido que o cliente estava procurando). Vou compartilhar os detalhes caso alguém dentro do mesmo contexto tenha esse problema:

Esse era um aplicativo Web baseado no Spring, no qual um bean "JaxWsPortProxyFactoryBean" foi configurado para expor um proxy para uma porta remota.

<bean id="ourPortJaxProxyService"
    class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean"
    p:serviceInterface="com.amir.OurServiceSoapPortWs"
    p:wsdlDocumentUrl="${END_POINT_BASE_URL}/OurService?wsdl"
    p:namespaceUri="http://amir.com/jaxws" p:serviceName="OurService"
    p:portName="OurSoapPort" />

O "END_POINT_BASE_URL" é uma variável de ambiente configurada em "setenv.sh" da instância do Tomcat que hospeda o aplicativo Web. O conteúdo do arquivo é algo como isto:

export END_POINT_BASE_URL="http://localhost:9001/BusinessAppServices"
#export END_POINT_BASE_URL="http://localhost:8765/BusinessAppServices"

O ";" ausente após cada linha causou o URL mal formado e, portanto, a resposta incorreta. Ou seja, em vez de "BusinessAppServices / OurService? Wsdl", o URL tinha um CR antes de "/". O "Monitor TCP / IP" foi bastante útil ao solucionar o problema.

Amir Keibi
fonte
0

No meu caso, recebi esse erro porque a API que usei poderia retornar os dados no formato XML ou JSON. Quando o testei usando um navegador, ele assumiu o formato XML, mas quando invoquei a mesma chamada de um aplicativo Java, a API retornou a resposta formatada em JSON, que naturalmente desencadeou um erro de análise.

zovits
fonte
0

Até eu tinha enfrentado um problema semelhante. A razão era algum caractere de lixo no início do arquivo.

Correção: basta abrir o arquivo em um editor de texto (testado em texto sublime), remover qualquer recuo, se houver, e copiar e colar todo o conteúdo do arquivo em um novo arquivo e salvá-lo. É isso aí!. Quando executei o novo arquivo, ele foi executado sem erros de análise.

Aditya Gaykar
fonte
0

Peguei o código do Dineshkumar e modifiquei para validar meu arquivo XML corretamente:

import org.apache.log4j.Logger;

public class Myclass{

private static final Logger LOGGER = Logger.getLogger(Myclass.class);

/**
 * Validate XML file against Schemas XSD in pathEsquema directory
 * @param pathEsquema directory that contains XSD Schemas to validate
 * @param pathFileXML XML file to validate
 * @throws BusinessException if it throws any Exception
 */
public static void validarXML(String pathEsquema, String pathFileXML) 
	throws BusinessException{	
	String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
	String nameFileXSD = "file.xsd";
	String MY_SCHEMA1 = pathEsquema+nameFileXSD);
	ParserErrorHandler parserErrorHandler;
	try{
		SchemaFactory schemaFactory = SchemaFactory.newInstance(W3C_XML_SCHEMA);
		
		Source [] source = { 
			new StreamSource(new File(MY_SCHEMA1))
			};
		Schema schemaGrammar = schemaFactory.newSchema(source);

		Validator schemaValidator = schemaGrammar.newValidator();
		schemaValidator.setErrorHandler(
			parserErrorHandler= new ParserErrorHandler());
		
		/** validate xml instance against the grammar. */
		File file = new File(pathFileXML);
		InputStream isS= new FileInputStream(file);
		Reader reader = new InputStreamReader(isS,"UTF-8");
		schemaValidator.validate(new StreamSource(reader));
		
		if(parserErrorHandler.getErrorHandler().isEmpty()&& 
			parserErrorHandler.getFatalErrorHandler().isEmpty()){
			if(!parserErrorHandler.getWarningHandler().isEmpty()){
				LOGGER.info(
				String.format("WARNING validate XML:[%s] Descripcion:[%s]",
					pathFileXML,parserErrorHandler.getWarningHandler()));
			}else{
				LOGGER.info(
				String.format("OK validate  XML:[%s]",
					pathFileXML));
			}
		}else{
			throw new BusinessException(
				String.format("Error validate  XML:[%s], FatalError:[%s], Error:[%s]",
				pathFileXML,
				parserErrorHandler.getFatalErrorHandler(),
				parserErrorHandler.getErrorHandler()));
		}		
	}
	catch(SAXParseException e){
		throw new BusinessException(String.format("Error validate XML:[%s], SAXParseException:[%s]",
			pathFileXML,e.getMessage()),e);
	}
	catch (SAXException e){
		throw new BusinessException(String.format("Error validate XML:[%s], SAXException:[%s]",
			pathFileXML,e.getMessage()),e);
	}
	catch (IOException e) {
		throw new BusinessException(String.format("Error validate XML:[%s], 
			IOException:[%s]",pathFileXML,e.getMessage()),e);
	}
	
}

}

RodH
fonte
0

Defina seu documento para formar da seguinte maneira:

<?xml version="1.0" encoding="UTF-8" ?>
<root>
    %children%
</root>
Pavel
fonte
0

Eu tive o mesmo problema com a primavera

MarshallingMessageConverter

e pelo código de pré-processo.

Talvez alguém precise de um motivo: BytesMessage #readBytes - lendo bytes ... e esqueci que a leitura é uma operação de direção única. Você não pode ler duas vezes.

Artem Ptushkin
fonte
0

Tente com BOMInputStream em apache.commons.io:

public static <T> T getContent(Class<T> instance, SchemaType schemaType, InputStream stream) throws JAXBException, SAXException, IOException {

    JAXBContext context = JAXBContext.newInstance(instance);
    Unmarshaller unmarshaller = context.createUnmarshaller();
    Reader reader = new InputStreamReader(new BOMInputStream(stream), "UTF-8");

    JAXBElement<T> entry = unmarshaller.unmarshal(new StreamSource(reader), instance);

    return entry.getValue();
}
Giuseppe Milazzo
fonte
0

Eu estava tendo o mesmo problema ao analisar o info.plistarquivo no meu mac. No entanto, o problema foi corrigido usando o seguinte comando que transformou o arquivo em um XML.

plutil -convert xml1 info.plist

Espero que ajude alguém.

Reaz Murshed
fonte
0

Eu tive o mesmo problema com alguns arquivos XML, resolvi ler o arquivo com codificação ANSI (Windows-1252) e escrever um arquivo com codificação UTF-8 com um pequeno script em Python. Eu tentei usar o Notepad ++, mas não tive sucesso:

import os
import sys

path = os.path.dirname(__file__)

file_name = 'my_input_file.xml'

if __name__ == "__main__":
    with open(os.path.join(path, './' + file_name), 'r', encoding='cp1252') as f1:
        lines = f1.read()
        f2 = open(os.path.join(path, './' + 'my_output_file.xml'), 'w', encoding='utf-8')
        f2.write(lines)
        f2.close()
Ângelo Polotto
fonte