在 GAE 上解析完全有效的 XML 时,“序言中不允许包含内容”

2022-08-31 07:24:47

在过去的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上进行远程调试的好方法)。尽管如此,使用我所拥有的原始手段,我已经尝试了一百万种方法,包括:

  • 带和不带序言的 XML
  • 带和不带换行符
  • 在序言中使用和不带“encoding=”属性
  • 两种换行符样式
  • 使用和不使用 HTTP 流中存在的分块信息

我已经尝试了其中大多数在多种组合中,它们会相互作用 - 什么都没有!我已达到机智的尽头。以前有没有人见过这样的问题,希望能对此有所了解?

谢谢!


答案 1

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

导致这种情况的另一种可能情况是,当任何内容出现在 XML 文档类型声明之前时。即,缓冲区中可能有这样的东西:

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

甚至是空格或特殊字符。

缓冲区中有一些称为字节顺序标记的特殊字符。在将缓冲区传递给解析器之前,请执行以下操作...

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

答案 2

我在记事本++中检查xml文件并保存文件时遇到了问题,尽管我有顶部的utf-8 xml标签<?xml version="1.0" encoding="utf-8"?>

通过将文件保存在notpad++中,使用编码(Tab)>以UTF-8编码:选中(以UTF-8-BOM编码)修复


推荐