私はこの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と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]+)<","<");
このエラーメッセージは、常に開始要素の無効なXMLコンテンツが原因です。たとえば、XML要素の先頭にある余分な小さなドット「。」。
「<?xml….
」の前の文字は、「org.xml.sax.SAXParseException:prolog」エラーメッセージでは許可されません。
“<?xml….
の前の小さなドット「。」
修正するには、“<?xml“
の前にある奇妙な文字をすべて削除するだけです。
参照: http://www.mkyong.com/Java/sax-error-content-is-not-allowed-in-prolog/
私は同じ問題に直面していました。私の場合、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
Xml宣言を削除すると解決しました
<?xml version='1.0' encoding='utf-8'?>
Notepad ++でxmlファイルを検査してファイルを保存するときに問題が発生しましたが、<?xml version="1.0" encoding="utf-8"?>
として最上位のutf-8 xmlタグがありました
Encoding(Tab)> UTF-8でエンコード(選択はUTF-8-BOMでエンコード)でnotpad ++にファイルを保存することで修正されました
私の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が上記で指摘したように、エンコードは一致する必要があります。
私は、xmlファイルで「プロローグでコンテンツが許可されていません」という同じ問題に直面していました。
ソリューション
最初、私のルートフォルダーは '#Filename'でした。
最初の文字「#」を削除すると、エラーが解決しました。
#filenameを削除する必要はありません...この方法で試してください。
FileオブジェクトまたはURLオブジェクトをunmarshallerメソッドに渡す代わりに、FileInputStreamを使用します。
File myFile = new File("........");
Object obj = unmarshaller.unmarshal(new FileInputStream(myFile));
問題の私の例では、解決策はドイツ語のウムラウト(äöü)をHTMLに相当するものに置き換えることでした...
「<?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です。
私の場合、build.xml
ファイルに問題がありました。これは、Build > Clean Project
に行くだけで解決しました。
「org.xml.sax.SAXParseException:コンテンツがプロローグで許可されていません」例外の上の原因は次のとおりです。
<?xml version='1.0' encoding='utf-8'?>
<?xml version='1.0' encoding='utf-8'?>
hello<?xml version='1.0' encoding='utf-16'?>
#
文字いくつかの内部バグにより、エラーコンテンツはprologでは許可されませんファイルコンテンツ自体が100%正しい場合にも表示されますただし、C:\Data\#22\file.xml
のようなファイル名を指定しています。
これは、他の特殊文字にも適用される可能性があります。
チェック方法:特殊文字のないパスにファイルを移動してエラーが消えた場合、それはこの問題でした。
スペースの代わりにタブ文字がありました。タブ「\ t」を置き換えると、問題が修正されました。
文書全体を切り取ってNotepad ++などのエディターに貼り付け、すべての文字を表示します。