org.xml.sax.SAXParseException:序言中不允许内容


161

我有一个基于Java的Web服务客户端,该客户端连接到Java Web服务(在Axis1框架上实现)。

我的日志文件中出现以下异常:

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)

11
如果您向我们展示了您要解析的XML,那将会有所帮助。(我希望前几行就可以了。)
Stephen C

感谢Stephen,我正在尝试从AXIS框架检索XML请求并将其粘贴到此处。因此,对上述错误的一般理解是XML格式不正确。
2011年

我遇到这个问题是因为我试图将xml文件的字符串名称而不是xml文件转换为字符串!:P
ʀʀʏ

Answers:


242

这通常是由XML声明之前的空白引起的,但是它可以是任何文本,例如破折号或任何字符。我说这通常是由空白引起的,因为人们认为空白始终是可忽略的,但事实并非如此。


经常发生的另一件事是UTF-8 BOM(字节顺序标记),如果将文档作为字符流传递给XML解析器而不是字节流,在将XML声明视为空白之前允许使用UTF-8 BOM

如果使用架构文件(.xsd)验证xml文件,并且其中一个架构文件具有UTF-8 BOM,则可能会发生同样的情况。


17
对于像我这样的每个人来说,他们都难以理解如何处理约翰·汉弗莱斯-w00te的建议:更改Document document = documentBuilder.parse(new InputSource(new StringReader(xml)))Document document = documentBuilder.parse(new InputSource(new ByteArrayInputStream(xml.getBytes("UTF-8"))))
RealMan,

32

其实除了Yuriy Zubarev的帖子

当您将不存在的xml文件传递给解析器时。例如你通过

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

当文件系统上仅存在C:/temp/abc.xml文件时

在任一情况下

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

要么

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

都给出相同的错误信息。

非常令人失望的错误,因为下面的跟踪

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

没有说“文件名不正确”或“这样的文件不存在”这一事实。就我而言,我拥有绝对正确的xml文件,并且不得不花2天的时间来确定真正的问题。


与尝试解析目录而不是文件名FWIW相同。
rogerdpack 2015年

... @ Egor这就是每个人都讨厌XML的原因。失去工作2天,这样一个愚蠢的失败..
Gewure

绝对同意@Gewure :)那是2012年的一些古老帖子,我什至忘记了它,但是是真的
Egor

1
当您具有正确的路径但带有特殊符号时也会发生这种情况,例如:C:\#MyFolder \ My.XML文件存在,但是“#”给XML解析器带来了问题... Java本身,以及M $ Windows,此文件夹名称没有问题....非常糟糕的异常消息行为..
Alex

26

尝试encoding="UTF-8"在序言中的字符串和终止符之间添加一个空格?>。在XML中,序言在文档的开头指定了该括号问号分隔的元素(而stackoverflow中的标记序言是指编程语言)。

补充:您序言部分前面的破折号是文档的一部分吗?那是错误,在序言前面有数据-<?xml version="1.0" encoding="UTF-8"?>


1
+1。我发现即使XML序言中包含空格,某些XML解析器也会阻止此异常-因此,我认为绝对值得一提的是,没有任何检查<?xml ver...

11

尝试使用freemarker解析XML文档时,我遇到了同样的问题(并解决了)。

XML文件头之前没有空格。

当且仅当文件编码和XML编码属性不同时,才会出现此问题(例如:标头中具有UTF-16属性的UTF-8文件)。

因此,我有两种解决问题的方法:

  1. 更改文件本身的编码
  2. 将标头UTF-16更改为UTF-8

1
我猜想通常在任何情况下解析器收到有关字符编码的冲突信息都可能导致此问题。
拉德瓦尔德2014年

9

这意味着XML格式错误或响应主体根本不是XML文档。


我检查了一下,看起来XML格式正确。这是快照:-<?xml版本=“ 1.0”编码=“ UTF-8”?> <soapenv:信封xmlns:soapenv =“ schemas.xmlsoap.org/soap/envelope ” xmlns:xsd =“ w3.org/ 2001 / XMLSchema “ xmlns:xsi =” w3.org/2001/XMLSchema-instance “> <soapenv:Header> <wsse:Security 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
是的,如果前面有破折号,它将破坏XML。
Yuriy Zubarev

7

仅仅花了4个小时来跟踪WSDL中的类似问题。事实证明,WSDL使用了一个XSD,该XSD导入了另一个名称空间XSD。导入的XSD包含以下内容:

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

注意空include元素!这是我苦难的根源。我想这是上述Egor文件找不到问题的一种变体。

+1令人失望的错误报告。



4

我的回答可能对您没有帮助,但通常可以解决此问题。

当您看到这种异常时,您应该尝试在任何十六进制编辑器中打开xml文件,有时您会在文件的开头看到其他字节,而文本编辑器不会显示该字节。

删除它们,您的xml将被解析。


4

有时是代码,而不是XML

以下代码,

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

也会导致此错误,

[致命错误]:1:1:prolog.org.xml.sax.SAXParseException中不允许包含内容;lineNumber:1;columnNumber:1;序言中不能有内容。

因为它试图解析字符串文字"file.xml"(而不是file.xml文件的内容)而失败,因为"file.xml"作为字符串的XML格式不正确。

修复:删除StringReader()

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

同样,脏缓冲区问题可能使残留垃圾在实际XML之前。如果您已经仔细检查了XML并仍然出现此错误,请记录传递给解析器的确切内容;有时实际(尝试)解析的内容令人惊讶。


1
由于我忘记applicaionContext.xml在代码中添加路径,因此该解决方案在正确的路径中进行了指导,而我没有检查代码只是在XML文件中查找错误
Mrinmoy

3

首先清理项目,然后重建项目。我也面临着同样的问题。此后一切都变好了。


2

如果所有其他方法都失败,请以二进制格式打开文件,以确保文件开头没有有趣的字符[在文件开头的3个不可打印字符,将文件标识为utf-8]。我们这样做并找到了一些。因此我们将文件从utf-8转换为ascii并成功运行。


2

对于相同的问题,我删除了以下行,

  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");

一切正常。不确定为什么UTF-8会出问题。让我感到震惊的是,它也适用于UTF-8。

我正在使用Windows-7 32位和带有Java * jdk1.6.0_13 *的Netbeans IDE。不知道它是如何工作的。


2

正如Mike Sokolov所指出的那样,可能的原因之一是标签之前存在一些字符(例如空格)。

如果将输入XML读取为字符串(而不是字节数组),则可以使用以下代码替换输入字符串,以确保擦除xml标记之前的所有“不必要”字符。

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

您需要确保输入的xml以xml标记开头。


2

在我的情况下,即使删除后我的应用程序中的web.xml仍然有多余的空间,我不得不还原chages及其修复程序,是的,我在tomcat中正在使用logging.propertiesweb.xml,但是即使我还原了错误不断显示,因此已解决))。

多余的空间

具体来说,我尝试在流中添加 org.apache.catalina.filters.ExpiresFilter.level = FINE 堆栈有关logging.properties的信息


1

我按照此处找到的说明进行操作,但遇到相同的错误。

我在记事本和XML记事本中尝试了几种方法来解决它(即更改编码,键入XML文件而不是复制粘贴等),但是没有任何效果。

当我在Notepad ++中编辑并保存XML文件时,问题得到解决(编码->不带BOM的utf-8)


1

对于所有遇到此错误的用户:警告:Catalina.start使用conf / server.xml:序言中不允许内容。

信息不是很丰富。但是,这实际上意味着conf / server.xml文件中存在垃圾。

我已经在其他XML文件中看到了这个确切的错误。此错误可能是由使用引入垃圾的文本编辑器进行更改引起的。

验证文件中是否有垃圾的方法是使用“十六进制编辑器”打开该文件。如果在此字符串之前看到任何字符,

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

这样会很垃圾

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

那是你的问题。解决方案是使用一个好的HEX编辑器。一种可以让您保存具有不同编码类型的文件的方法。

然后只需将其另存为UTF-8。使用XML文件的某些系统可能需要将其另存为UTF NO BOM,这意味着使用“无字节顺序标记”

希望这可以帮助某人!!



1

要解决Unix / Linux系统上的BOM表问题:

  1. 检查是否存在不需要的BOM字符: hexdump -C myfile.xml | more 不需要的BOM字符将出现在文件开头,如下所示:...<?xml>

  2. 或者,执行file myfile.xml。具有BOM表字符的文件将显示为:myfile.xml: XML 1.0 document text, UTF-8 Unicode (with BOM) text

  3. 使用以下方法修复单个文件: tail -c +4 myfile.xml > temp.xml && mv temp.xml myfile.xml

  4. 重复1或2以检查文件是否已清除。可能还很明智的做法view myfile.xml是检查内容是否已中止。

这是一个bash脚本,用于清理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

0

只是对未来的另一种思考。出现此错误的情况可能是,当一个人将XML窗口作为活动显示而没有引起注意时,他们只是随机地按下Delete键或其他键。在我的Web应用程序中使用struts.xml文件之前,这已经发生在我身上。笨拙的手肘...


我确信我不是击中任何键
疯d

0

我也一样

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

,当我的应用程序正在为RestFull Web服务调用创建XML响应时。在创建XML格式字符串时,我用<和>替换了&lt和&gt,然后错误消失了,并且得到了正确的响应。不知道它是如何工作的,但是它能工作。

样本

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

0

我遇到过同样的问题。

首先,我将XML文件下载到本地桌面, Content is not allowed in prolog在将文件导入门户网站服务器的过程中。甚至从视觉上看,文件对我来说也不错,但不知何故它已损坏。

因此,我重新下载了相同的文件并尝试了相同的文件,并且该文件可以正常工作。


0

最近,我们遇到了同样的问题,结果是URL错误,因此出现了标准的403 HTTP响应(这显然不是客户端正在寻找的有效XML)。我将分享细节,以防在相同上下文中有人遇到此问题:

这是一个基于Spring的Web应用程序,其中将“ JaxWsPortProxyFactoryBean” bean配置为公开远程端口的代理。

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

“ END_POINT_BASE_URL”是在托管Web应用程序的Tomcat实例的“ setenv.sh”中配置的环境变量。该文件的内容如下所示:

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

缺少的“;” 在每一行之后导致网址格式错误,从而导致错误的响应。也就是说,URL在“ /”之前具有CR,而不是“ BusinessAppServices / OurService?wsdl”。解决问题时,“ TCP / IP Monitor”非常方便。


0

就我而言,出现此错误是因为我使用的API可以XML或JSON格式返回数据。当我使用浏览器测试它时,它默认为XML格式,但是当我从Java应用程序调用相同的调用时,API返回JSON格式的响应,这自然触发了解析错误。


0

甚至我也遇到过类似的问题。原因是文件开头有一些垃圾字符。

修复:只需在文本编辑器中打开文件(在Sublime文本上进行了测试),如果文件中有任何缩进,则将其删除,然后复制并将文件的所有内容粘贴到新文件中并保存。而已!。当我运行新文件时,它运行时没有任何解析错误。


0

我使用了Dineshkumar的代码,并进行了修改以正确地验证我的XML文件:

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);
	}
	
}

}


0

将文档设置为如下形式:

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

0

我春天也有同样的问题

MarshallingMessageConverter

并通过预处理代码。

也许有人会需要理由: BytesMessage #readBytes-读取字节..而我忘了读取是一种方向的操作。您无法阅读两次。


0

尝试使用apache.commons.io中的BOMInputStream:

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();
}

0

info.plist在Mac中解析文件时遇到了同样的问题。但是,使用以下命令将文件转换为XML的问题得以解决。

plutil -convert xml1 info.plist

希望能对某人有所帮助。


0

我对某些XML文件有同样的问题,我解决了使用ANSI编码(Windows-1252)读取文件并使用Python中的小脚本编写使用UTF-8编码的文件的问题。我尝试使用Notepad ++,但没有成功:

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()
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.