【问题标题】:org.xml.sax.SAXParseException: Content is not allowed in prologorg.xml.sax.SAXParseException: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++ 和更改编码对我来说很好!

标签: java xml


【解决方案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 中,序言在文档的开头指定这个括号-问号分隔的元素(而在 stackoverflow 中的标签序言是指编程语言)。

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

【讨论】:

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

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

XML 文件头前没有空格。

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

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

  1. 更改文件本身的编码
  2. 将标头 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 问题:

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

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

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

          4. 重复 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
                                            

                                            希望对某人有所帮助。

                                            【讨论】:

                                              猜你喜欢
                                              • 2018-12-03
                                              • 1970-01-01
                                              • 2013-07-05
                                              • 2012-11-19
                                              • 2011-06-01
                                              • 2011-07-23
                                              相关资源
                                              最近更新 更多