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 格式正确。这是快照:-只花了 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 字符将出现在文件开头,为 ...<?xml>
或者,执行file myfile.xml
。带有 BOM 字符的文件将显示为:myfile.xml: XML 1.0 document text, UTF-8 Unicode (with BOM) text
修复单个文件:tail -c +4 myfile.xml > temp.xml && 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.properties
和 web.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 格式字符串时,我用 替换了 < 和 >,然后错误消失了,我得到了正确的响应。不知道它是如何工作的,但它确实有效。
样本:
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 中不允许内容的主要内容,如果未能解决你的问题,请参考以下文章