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

Posted

技术标签:

【中文标题】org.xml.sax.SAXParseException:prolog 中不允许内容【英文标题】:org.xml.sax.SAXParseException: Content is not allowed in prolog 【发布时间】:2011-07-05 13:15:57 【问题描述】:

我有一个基于 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)

【问题讨论】:

如果您向我们展示您尝试解析的 XML,将会有所帮助。 (我希望前几行就可以了。) 谢谢斯蒂芬,我正在尝试从 AXIS 框架检索 XML 请求并将其粘贴到此处。所以对上述错误的一般理解是 XML 格式不正确。 我遇到了这个问题,因为我试图将 xml 文件的字符串名称而不是 xml 文件转换为字符串! :P Notepad++ 和更改编码对我来说很好! 【参考方案1】:

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


另一件经常发生的事情是 UTF-8 BOM(字节顺序标记),如果文档是作为字符流而不是字节流传递给 XML 解析器。

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

【讨论】:

对于像我这样难以理解如何处理 John Humphreys 的每个人 - w00te 的建议:将 Document document = documentBuilder.parse(new InputSource(new StringReader(xml))) 更改为 Document document = documentBuilder.parse(new InputSource(new ByteArrayInputStream(xml.getBytes("UTF-8"))))【参考方案2】:

其实除了尤里祖巴列夫的帖子

当您将不存在的 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。 ... @Egor 这就是为什么每个人都讨厌 XML。因为如此愚蠢的失败而失去了 2 天的工作.. 完全同意@Gewure :) 那是 2012 年的一篇古老帖子,我什至忘记了,但确实如此 这也会发生,当你有一个正确的路径,但有特殊符号,如: C:\#MyFolder\My.XML 文件存在,但“#”给 XML 解析器带来问题。 .. Java 本身以及 M$ Windows 对这个文件夹名称没有问题.. 非常糟糕的异常消息行为 .... 这是我的类似问题。我花了几个小时试图了解问题所在,但我什至没有考虑过格式错误的参数。【参考方案3】:

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

已添加:该破折号是否位于文档序言部分的前面?那将是那里的错误,在序言前面有数据-<?xml version="1.0" encoding="UTF-8"?>

【讨论】:

+1。我发现即使 XML 序言包含空格,一些 XML 解析器也会拒绝此异常 - 所以我认为绝对值得检查 <?xml ver... 位之前没有任何内容。【参考方案4】:

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

XML 文件头前没有空格。

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

所以我有两种解决问题的方法:

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

【讨论】:

我猜在一般情况下,解析器收到有关字符编码的冲突信息的任何情况都可能导致此问题。 这个答案已经很久了,但这在 2021 年对我有用。我是 Jenkins 管道中的用户 Pester 测试,并不断收到“prolog 中的内容”错误。我看到 JUnit 结果文件是 UTF16 格式的,我出于习惯将文件输出到 UTF8 格式。当我更改为 UTF-16 时,它起作用了。 Invoke-Pester -Script resources/*.Tests.ps1 -PassThru | ConvertTo-JUnitReport -AsString | Out-File -Encoding utf-16 .\results.xml【参考方案5】:

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

【讨论】:

我检查过,看起来 XML 格式正确。这是快照:-schemas.xmlsoap.org/soap/envelope" xmlns:xsd="w3.org/2001/XMLSchema" xmlns:xsi="@ 987654323@">
docs.oasis-open.org/wss/2004/01/…"soapenv:mustUnderstand="1">....
.XX..
是的,如果前面有一个破折号,它会破坏 XML。 是的,我不小心添加了一个字母,导致 XML 无效并导致错误。谢谢!【参考方案6】:

只花了 4 个小时在 WSDL 中追踪一个类似的问题。原来 WSDL 使用了一个导入另一个命名空间 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 表示令人失望的错误报告。

【讨论】:

【参考方案7】:

我的回答可能对你没有帮助,但它通常有助于解决这个问题。

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

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

【讨论】:

【参考方案8】:

在我的情况下,完全删除 'encoding="UTF-8"' 属性是有效的。

这看起来像是字符集编码问题,可能是因为您的文件不是真正的 UTF-8。

【讨论】:

【参考方案9】:

有时是代码,而不是 XML

以下代码,

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

也会导致这个错误,

[致命错误] :1:1: prolog.org.xml.sax.SAXParseException 中不允许有内容;行号:1;列号:1;序言中不允许有内容。

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

修复:删除StringReader()

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

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

【讨论】:

这个解决方案在正确的路径中引导,因为我忘记在代码中添加applicaionContext.xml 路径,并且没有签入代码只是在 XML 文件中查找错误【参考方案10】:

首先清理项目,然后重建项目。我也面临同样的问题。在这之后一切都好起来了。

【讨论】:

【参考方案11】:

修复 Unix / Linux 系统上的 BOM 问题:

    检查是否有不需要的 BOM 字符: hexdump -C myfile.xml | more 不需要的 BOM 字符将出现在文件开头,为 ...&lt;?xml&gt;

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

    修复单个文件:tail -c +4 myfile.xml &gt; temp.xml &amp;&amp; mv temp.xml myfile.xml

    重复 1 或 2 以检查文件是否已清理。做view myfile.xml 来检查内容是否留下来可能也是明智的。

这是一个清理整个 XML 文件文件夹的 bash 脚本:

#!/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

【讨论】:

【参考方案12】:

我尝试过的[无效]

在我的情况下,我的应用程序中的web.xml 有额外的空间。即使 我删除了;它没有用!。

我在我的 tomcat 中使用 logging.propertiesweb.xml,但即使在我恢复之后,错误仍然存​​在!。

解决方案

具体来说,我尝试添加

org.apache.catalina.filters.ExpiresFilter.level = FINE

Tomcat expire filter is not working correctly

【讨论】:

【参考方案13】:

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

【讨论】:

【参考方案14】:

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

  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。不知道它是如何工作的。

【讨论】:

【参考方案15】:

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

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

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

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

【讨论】:

【参考方案16】:

我按照here 找到的说明进行操作,但遇到了同样的错误。

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

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

【讨论】:

【参考方案17】:

在我的例子中,我收到了这个错误,因为我使用的 API 可以返回 XML 或 JSON 格式的数据。当我使用浏览器测试它时,它默认为 XML 格式,但是当我从 Java 应用程序调用相同的调用时,API 返回 JSON 格式的响应,这自然会触发解析错误。

【讨论】:

【参考方案18】:

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

信息量不是很大..但这实际上意味着您的 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 这意味着“无字节顺序标记”

希望这对那里的人有所帮助!

【讨论】:

【参考方案19】:

对我来说,Build->Clean 修复了所有问题!

【讨论】:

【参考方案20】:

我在处理一些 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()

【讨论】:

Notepad++ 和更改编码对我来说很好!【参考方案21】:

只是对这个未来的一个额外的想法。出现此错误的原因可能是当他们将 XML 窗口作为活动显示并且没有注意时,他们只是随机点击了删除键或其他键。在我的 Web 应用程序中使用 struts.xml 文件之前,我也遇到过这种情况。笨拙的肘部......

【讨论】:

我确定我没有按任何键【参考方案22】:

我也是这样的

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

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

样本

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

【讨论】:

【参考方案23】:

我遇到了同样的问题。

首先我将 XML 文件下载到本地桌面,在将文件导入到门户服务器期间我得到了Content is not allowed in prolog。即使是视觉文件对我来说看起来也不错,但不知何故它已损坏。

所以我重新下载了相同的文件并尝试了相同的方法,它成功了。

【讨论】:

【参考方案24】:

我们最近遇到了同样的问题,结果证明是错误的 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 并因此导致错误响应之后。也就是说,URL 在“/”之前有一个 CR,而不是“BusinessAppServices/OurService?wsdl”。 “TCP/IP Monitor”在解决问题时非常方便。

【讨论】:

【参考方案25】:

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

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

【讨论】:

【参考方案26】:

我获取了 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);
	
	


【讨论】:

【参考方案27】:

将您的文档设置为如下形式:

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

【讨论】:

【参考方案28】:

我也遇到了同样的问题

编组消息转换器

并通过预处理代码。

也许有人需要理由: BytesMessage #readBytes - 读取字节.. 我忘记了读取是单向操作。 你不能读两遍。

【讨论】:

【参考方案29】:

尝试使用 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();

【讨论】:

【参考方案30】:

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

plutil -convert xml1 info.plist

希望对某人有所帮助。

【讨论】:

以上是关于org.xml.sax.SAXParseException:prolog 中不允许内容的主要内容,如果未能解决你的问题,请参考以下文章