[解決済み] GAEで完全に有効なXMLをパースする際に「Prologではコンテンツが許可されていません」と表示される。
質問
この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でエンコードされていない文字などがないか、2重、3重、4重にチェックしました。バイト順マークやその類のものがないか、配列でバイトごとに見てみました。何もありません。私が投げかけたあらゆる検証テストに合格しています。さらに不思議なことに、Saxonベースのパーサーを使っても同じことが起こります。しかし、GAE上だけで、私のローカル環境ではいつもうまくいきます。
完全に動作する環境でしかデバッガを実行できない場合、コードをトレースして問題を見つけるのは非常に困難です(GAEでリモートデバッグする良い方法は見つかっていません)。それでも、私が持っている原始的な手段を使って、以下のようなアプローチを100万回ほど試してみました。
- プロローグ付きXMLとプロローグなし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]+)<","<");
関連
-
[解決済み】エラー:配列または java.lang.Iterable のインスタンスに対してのみ反復処理を行うことができます。
-
[解決済み】このコンパイルユニットは名前付きモジュールに関連しているため、名前付きパッケージeclipseを宣言する必要があります。
-
[解決済み】Java、"変数名 "を変数に解決することができない
-
[解決済み】「error: '.class' expected」の意味と修正方法について
-
[解決済み】-XX:MaxPermSizeは何をするのですか?
-
[解決済み】Javaメソッドスタブ
-
[解決済み】Javaのswitch文。定数式が必要だが、定数である
-
[解決済み】接続Java - MySQL : 公開鍵の取得は許可されていません。
-
[解決済み】フォルダに書き込もうとすると「java.nio.file.AccessDeniedException」が発生する件
-
[解決済み] org.xml.sax.SAXParseException: コンテンツはプロローグで許可されていません
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】エラー:'if'のない'else'エラー
-
[解決済み】javaで指定されたファイルが見つからない
-
[解決済み】スレッド「main」での例外 java.lang.StringIndexOutOfBoundsException: 文字列のインデックスが範囲外です。0 [閉店]
-
[解決済み] メソッドがそのスーパークラスのメソッドをオーバーライドしない
-
[解決済み】「java -cp」と「java -jar」の違い?
-
[解決済み】Eclipseで「JUnitテストが見つかりませんでした。
-
[解決済み】Java LinkedListでNodesを使用する
-
[解決済み] java.sql.SQLException を取得しました。ResultSet が終了した後の操作は許可されません。
-
[解決済み】Java: GZIPInputStreamの作成に失敗しました。GZIP形式ではありません
-
[解決済み] org.xml.sax.SAXParseException: コンテンツはプロローグで許可されていません