在GAE上解析完全有效的XML时,“prolog中不允许使用内容”

时间:2010-06-13 02:52:42

标签: java xml google-app-engine parsing stax

在过去的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用于“隐形字符”或非UTF8编码字符等。我在数组中逐字节地查看字节顺序标记或类似的东西。没有;它通过我可以抛出的每个验证测试。更奇怪的是,如果我使用基于Saxon的解析器,它也会发生 - 但仅在GAE上,它总是在我的本地环境中正常工作。

当我只能在一个完美运行的环境上运行调试器时,很难跟踪问题的代码(我没有找到任何好的方法来远程调试GAE)。然而,使用我所拥有的原始方法,我已经尝试了一百万种方法,包括:

  • 包含和不包含prolog的XML
  • 有无换行符
  • 有和没有prolog的“encoding =”属性
  • 两种换行样式
  • 有和没有HTTP流中存在的分块信息

我已经尝试了多种组合中的大多数,因为它们是有意义的,它们会互动 - 没有!我的智慧结束了。有没有人在此之前看到过这样的问题,希望能够对此有所了解?

谢谢!

15 个答案:

答案 0 :(得分:101)

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

甚至是空格或特殊字符。

有一些称为字节顺序标记的特殊字符可能位于缓冲区中。 在将缓冲区传递给Parser之前,请执行此操作...

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

答案 1 :(得分:7)

此错误消息始终由begin元素中的无效XML内容引起。例如,XML元素开头的额外小点“。”。

<?xml….”之前的任何字符都会导致上面的“ org.xml.sax.SAXParseException:prolog 中不允许使用内容”错误消息。

“<?xml….

之前的小点“

要解决此问题,只需删除“<?xml“之前的所有奇怪字符。

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

答案 2 :(得分:5)

我遇到了同样的问题。在我的例子中,XML文件是从c#程序生成的,并被送入AS400进行进一步处理。在一些分析确定我在生成XML文件时使用UTF8编码,而javac(在AS400中)使用&#34; UTF8而没有BOM&#34;。 因此,必须编写类似于下面提到的额外代码:

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

答案 3 :(得分:4)

删除xml声明即可解决

<?xml version='1.0' encoding='utf-8'?>

答案 4 :(得分:3)

我在用notepad ++检查xml文件并保存文件时遇到了问题,尽管我的utf-8 xml顶级标签为conditionTable.register(UINib(nibName: "ConditionCell", bundle: nil), forCellReuseIdentifier: "conditionCell")

通过使用Encoding(Tab)将文件保存在notpad ++中>通过UTF-8编码:已选中(在UTF-8-BOM中为编码)来解决

答案 5 :(得分:2)

我在我的xml文件中遇到了一个名为“prolog中不允许内容”的问题。

<强>解决方案

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

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

无需删除#filename ... 试试这种方式..

不使用File或URL对象传递给unmarshaller方法,而是使用FileInputStream。

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

答案 6 :(得分:2)

在我的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上面提到的那样,编码需要匹配。

答案 7 :(得分:0)

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

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

答案 8 :(得分:0)

在我的问题实例中,解决方案是用他们的HTML等效替换德语变音符号(äöü)......

答案 9 :(得分:0)

下面的原因是“org.xml.sax.SAXParseException:prolog中不允许使用内容”异常。

  1. 首先检查schema.xsd和file.xml的文件路径。
  2. XML和XSD(或DTD)中的编码应该相同 XML文件头:<?xml version='1.0' encoding='utf-8'?>
    XSD文件头:<?xml version='1.0' encoding='utf-8'?>
  3. 如果在XML文档类型声明之前有任何内容.i.e:hello<?xml version='1.0' encoding='utf-16'?>

答案 10 :(得分:0)

就我而言,我遇到了build.xml文件的问题。只需转到Build > Clean Project即可解决此问题。

答案 11 :(得分:0)

本着&#34的精神;只需在&lt;?xml&#34;之前删除所有那些奇怪的字符,这里是我的Java代码,它通过BufferedReader输入效果很好:

    BufferedReader test = new BufferedReader(new InputStreamReader(fisTest));
    test.mark(4);
    while (true) {
        int earlyChar = test.read();
        System.out.println(earlyChar);
        if (earlyChar == 60) {
            test.reset();
            break;
        } else {
            test.mark(4);
        }
    }

FWIW,我看到的字节是(十进制):239,187,191。

答案 12 :(得分:0)

意外原因:文件路径中的#个字符

由于某些内部错误,如果文件内容本身为100%正确,但是您提供的文件名如下,也会出现错误 序言中不允许内容 C:\Data\#22\file.xml

这可能也适用于其他特殊字符。

如何检查:如果将文件移到没有特殊字符的路径中并且错误消失了,那么就是这个问题。

答案 13 :(得分:0)

我今天捕获了相同的错误消息。 解决方案是将文档从具有BOM表的UTF-8更改为不具有BOM表的UTF-8

答案 14 :(得分:0)

我在 Mac OS 中压缩了 xml 并将其发送到 Windows 机器,默认压缩更改了这些文件,因此编码发送了此消息。