web-dev-qa-db-ja.com

GAEで完全に有効なXMLを解析する場合の「コンテンツはプロローグで許可されていません」

私はこの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でリモートデバッグする良い方法が見つかりませんでした)。それにもかかわらず、私が持っている原始的な手段を使用して、私は以下を含む100万のアプローチを試みました:

  • プロローグありとなしのXML
  • 改行ありとなし
  • プロローグの「encoding =」属性の有無
  • 両方の改行スタイル
  • HTTPストリームに存在するチャンク情報の有無にかかわらず

そして、これらのほとんどを複数の組み合わせで試してみました。私は機知に富んでいます。このような問題を以前に見たことがありますか?

ありがとう!

84
Adrian Petrescu

XMLとXSD(またはDTD)のエンコーディングは異なります。
XMLファイルヘッダー:<?xml version='1.0' encoding='utf-8'?>
XSDファイルヘッダー:<?xml version='1.0' encoding='utf-16'?>

これを引き起こす可能性のあるもう1つのシナリオは、XMLドキュメントタイプ宣言の前に何かが来る場合です。つまり、バッファに次のようなものがあるかもしれません:

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

またはスペースまたは特殊文字でさえ。

バッファー内にある可能性のあるバイトオーダーマーカーと呼ばれる特殊文字がいくつかあります。バッファーをパーサーに渡す前にこれを行います...

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

このエラーメッセージは、常に開始要素の無効なXMLコンテンツが原因です。たとえば、XML要素の先頭にある余分な小さなドット「。」。

<?xml….」の前の文字は、「org.xml.sax.SAXParseException:prolog」エラーメッセージでは許可されません。

“<?xml….の前の小さなドット「

修正するには、“<?xml“の前にある奇妙な文字をすべて削除するだけです。

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

7
Sunmit Girme

私は同じ問題に直面していました。私の場合、XMLファイルはc#プログラムから生成され、さらに処理するためにAS400にフィードされました。いくつかの分析の後、XMLファイルの生成中にUTF8エンコーディングを使用しているのに対し、javac(AS400内)は「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
5
Saturn CAU

Xml宣言を削除すると解決しました

<?xml version='1.0' encoding='utf-8'?>
4
F.O.O

Notepad ++でxmlファイルを検査してファイルを保存するときに問題が発生しましたが、<?xml version="1.0" encoding="utf-8"?>として最上位のutf-8 xmlタグがありました

Encoding(Tab)> UTF-8でエンコード(選択はUTF-8-BOMでエンコード)でnotpad ++にファイルを保存することで修正されました

3
techloris_109

私の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.

2行目を更新したとき

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

オブジェクトを正常にデシリアライズできました。そのため、Romainが上記で指摘したように、エンコードは一致する必要があります。

2
dfritch

私は、xmlファイルで「プロローグでコンテンツが許可されていません」という同じ問題に直面していました。

ソリューション

最初、私のルートフォルダーは '#Filename'でした。

最初の文字「#」を削除すると、エラーが解決しました。

#filenameを削除する必要はありません...この方法で試してください。

FileオブジェクトまたはURLオブジェクトをunmarshallerメソッドに渡す代わりに、FileInputStreamを使用します。

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

問題の私の例では、解決策はドイツ語のウムラウト(äöü)をHTMLに相当するものに置き換えることでした...

0
MBaas

「<?xmlの前にある奇妙な文字をすべて削除する」という精神で、ここに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、私が見ていたバイトは(10進数で):239、187、191です。

0
Tamias

私の場合、build.xmlファイルに問題がありました。これは、Build > Clean Projectに行くだけで解決しました。

0
Muz

「org.xml.sax.SAXParseException:コンテンツがプロローグで許可されていません」例外の上の原因は次のとおりです。

  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文書型宣言の前に何かがある場合、つまりhello<?xml version='1.0' encoding='utf-16'?>
0
Avinash Dubey

予期しない理由:ファイルパスに#文字

いくつかの内部バグにより、エラーコンテンツはprologでは許可されませんファイルコンテンツ自体が100%正しい場合にも表示されますただし、C:\Data\#22\file.xmlのようなファイル名を指定しています。

これは、他の特殊文字にも適用される可能性があります。

チェック方法:特殊文字のないパスにファイルを移動してエラーが消えた場合、それはこの問題でした。

0
miroxlav

スペースの代わりにタブ文字がありました。タブ「\ t」を置き換えると、問題が修正されました。

文書全体を切り取ってNotepad ++などのエディターに貼り付け、すべての文字を表示します。

0
SoloPilot