java - 在GAE上,当解析完全有效的XML时"Content is not allowed in prolog"

  显示原文与译文双语对照的内容

我一直在打我的头在这种绝对激怒 Bug 过去 48小时,所以我想最后认输,试着问问这里之前我把我的笔记本电脑出窗外。

我试图从调用 AWS SimpleDB的调用中解析响应 XML 。 响应返回的线路很好;例如它可能看起来像:


<?xml version="1.0" encoding="utf-8"?> 
<ListDomainsResponse xmlns="http://sdb.amazonaws.com/doc/2009-04-15/">
 <ListDomainsResult>
 <DomainName>Audio</DomainName>
 <DomainName>Course</DomainName>
 <DomainName>DocumentContents</DomainName>
 <DomainName>LectureSet</DomainName>
 <DomainName>MetaData</DomainName>
 <DomainName>Professors</DomainName>
 <DomainName>Tag</DomainName>
 </ListDomainsResult>
 <ResponseMetadata>
 <RequestId>42330b4a-e134-6aec-e62a-5869ac2b4575</RequestId>
 <BoxUsage>0.0000071759</BoxUsage>
 </ResponseMetadata>
</ListDomainsResponse>

我把这个XML传递给一个


XMLEventReader eventReader = xmlInputFactory.createXMLEventReader(response.getContent());

然后调用 eventReader.nextEvent(); 多次获取我想要的数据。

这是一个奇怪的部分--它在本地服务器内部工作很大。 响应进来了,我对它进行了分析,对大家高兴。 问题是,当我将代码部署到 Google App Engine, 即将离任的请求仍能工作,和响应xml在我看来 100%相同的和正确的,但是响应无法解析以下异常:


com.amazonaws.http.HttpClient handleResponse: Unable to unmarshall response (ParseError at [row,col]:[1,1]
Message: Content is not allowed in prolog.): <?xml version="1.0" encoding="utf-8"?> 
<ListDomainsResponse xmlns="http://sdb.amazonaws.com/doc/2009-04-15/"><ListDomainsResult><DomainName>Audio</DomainName><DomainName>Course</DomainName><DomainName>DocumentContents</DomainName><DomainName>LectureSet</DomainName><DomainName>MetaData</DomainName><DomainName>Professors</DomainName><DomainName>Tag</DomainName></ListDomainsResult><ResponseMetadata><RequestId>42330b4a-e134-6aec-e62a-5869ac2b4575</RequestId><BoxUsage>0.0000071759</BoxUsage></ResponseMetadata></ListDomainsResponse>
javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,1]
Message: Content is not allowed in prolog.
 at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(Unknown Source)
 at com.sun.xml.internal.stream.XMLEventReaderImpl.nextEvent(Unknown Source)
 at com.amazonaws.transform.StaxUnmarshallerContext.nextEvent(StaxUnmarshallerContext.java:153)
. . . (rest of lines omitted)

我有两倍三倍四倍检查这个xml'不可见字符'或者non-UTF8编码字符, 等等 我看着它在数组 byte-by-byte byte-order-marks或本质的东西。 没什么,它通过了我可以在它上面抛出的每个验证测试。 即使是陌生人,它也会发生在我使用Saxon-based解析器和--的时候,它总是在我的本地环境中工作良好。

当我只能在一个完美的( 在GAE上没有找到任何远程调试的好方法) 环境下运行调试时,很难跟踪问题的代码。 不过,使用原语意味着我已经尝试了上百万种方法,包括:

  • 带或者不带prolog的XML
  • 带和不带换行符
  • 在序言中使用和不使用"encoding="属性
  • 两种换行样式
  • 在HTTP流中包含和不包含块信息

我已经在多个组合中尝试了很多,它们有意义,它们会相互影响 -- ! 我在我的末端。 之前有人看到过这样的问题,希望能对它有所帮助?

谢谢!

时间: 作者:

你的XML和 XSD ( 或者 DTD ) 中的编码是不同的。
XML文件头: <?xml version='1.0' encoding='utf-8'?>
XSD文件头: <?xml version='1.0' encoding='utf-16'?>

导致这一点的另一个可能的场景是,在XML文档类型声明之前。 例如 在缓冲区中可能有类似的内容:


helloworld<?xml version="1.0" encoding="utf-8"?> 

甚至一个空格或者特殊字符。

有一些特殊字符叫做字节顺序标记,它们可以在缓冲区中。 在将缓冲区传递给解析器之前,请执行这里操作。


String xml ="<?xml.. .";
xml = xml.trim().replaceFirst("^([W]+)<","<");

作者:

这里错误消息总是由开始元素中的无效XML内容引起的。 例如在XML元素的开头有额外的小点"。"。

" <?xml…."之前的任何字符都会导致" org.xml.sax.SAXParseException:" 在序言中不允许内容"错误消息"。

一个小圆点磅。"<?xml…. 之前

要修复它,只需在 "<?xml" 之前删除所有怪异字符。

引用:http://www.mkyong.com/java/sax-error-content-is-not-allowed-in-prolog/

在我的xml文件中,标题类似于:


<?xml version="1.0" encoding="utf-16"?/>

在一个测试文件中,我读取文件字节并将数据解码为 UTF-8 ( 未实现这里文件中的头是 utf-16 ) 来创建一个字符串。


byte[] data = Files.readAllBytes(Paths.get(path));
String dataString = new String(data,"UTF-8");

当我试图将这个字符串反序列化到一个对象时,我看到了同样的错误:


javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,1]
Message: Content is not allowed in prolog.

当我更新第二行的时候


String dataString = new String(data,"UTF-16");

我可以很好地反序列化对象。 因此,就像Romain上面提到的,编码需要匹配。

作者:

我有一个制表符而不是空格。 替换选项卡't'修复了问题。

将整个文档剪切并粘贴到编辑器中,如 NotePad++ 并显示所有字符。

我遇到了同样的问题。 在我的案例中,XML文件是从 C# 程序生成的,并为进一步处理而送入 AS400. 经过分析发现,我在生成XML文件时使用UTF8编码,而 javac ( 在小型机) 使用"不带bom的UTF8"。 因此,必须编写类似下面提到的额外代码:


//create encoding with no BOM
Encoding outputEnc = new UTF8Encoding(false); 
//open file with encoding
TextWriter file = new StreamWriter(filePath, false, outputEnc); 

file.Write(doc.InnerXml);
file.Flush();
file.Close();//save and close it

作者:
作者:

我在我的xml文件中遇到了一个名为"在序言中不允许内容"的问题。

解决方案

最初我的root 文件夹是'# 文件名'。

删除第一个字符'δ #'时,错误得到了解决。

不需要删除 #filename... 用这种方式试试。

不将文件或者URL对象传递给分组编组方法,而是使用 FileInputStream 。


File myFile = new File("........");
Object obj = unmarshaller.unmarshal(new FileInputStream(myFile));

作者:
...