11

内部に UTF-8 ( )のString連結バイナリがあります。JAXB は、このような文字を含む XML ドキュメントを喜んでマーシャリングしますが、アンマーシャリングに失敗します。0"A\u0000B"

final JAXBContext jaxbContext = JAXBContext.newInstance(Root.class);
final Marshaller marshaller = jaxbContext.createMarshaller();
final Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();

Root root = new Root();
root.value = "A\u0000B";

final ByteArrayOutputStream os = new ByteArrayOutputStream();
marshaller.marshal(root, os);

unmarshaller.unmarshal(new ByteArrayInputStream(os.toByteArray()));

ルート クラスは単純です。

@XmlRootElement
class Root { @XmlValue String value; }

出力 XML には、と(16 進数: )0の間にバイナリも含まれているため、非整列化中に次のエラーが発生します。AB41 00 42

org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 63; 
An invalid XML character (Unicode: 0x0) was found in the element content of the document.

興味深いことに、未加工の DOM API ( example ) を使用すると、 escaped 0:A�Bが生成されますが、それを読み戻そうとすると、同様のエラーが発生します。また0、(バイナリでもエスケープでもない) は、どの XML パーサーでも許可されていませんxmllint( Python + Expat: Error on entitiesも参照)。

私の質問:

しかし、Java の成熟した XML スタック (私は 1.7.0_05 を使用しています) は、デフォルトで、または簡単な設定でこれを処理するべきではありませんか? エスケープ、無視、または迅速な失敗を探していますが、無効な XML を生成するデフォルトの動作は受け入れられません。このような基本的な機能は、クライアント側で追加のコーディングを必要とすべきではないと考えています。

4

1 に答える 1

3

JAXB/DOM API が、読み戻せない無効な XML ドキュメントの作成を許可するのはなぜですか? マーシャリング中に高速で失敗するべきではありませんか?

  1. 実装者に尋ねる必要があります。

  2. シリアル化されたすべてのデータ文字をチェックする費用は正当化されないと彼らが考えた可能性があります...特にパーサーがそれらをもう一度チェックする場合.

  3. この方法でシリアライザーを実装することを決定した (または誤って実行した) 場合、既定で厳密なチェックを行うように動作を変更すると、違法な XML をシリアル化できることに依存する既存のコードが壊れてしまいます。

しかし、Java の成熟した XML スタック (私は 1.7.0_05 を使用しています) は、デフォルトで、または簡単な設定でこれを処理するべきではありませんか?

必ずしもそうではありません...上記の理由 2 を受け入れる場合。単純な設定でも、パフォーマンスに測定可能な影響を与える可能性があります。


また、0 (バイナリでもエスケープでもない) は、XML パーサーまたは xmllint では許可されていません ...

その通りです!XML 仕様で禁止されています。

ただし、より興味深いテストは、他の XML スタックを使用して不正な文字を含む XML を生成しようとするとどうなるかを確認することです。


エレガントでグローバルなソリューションはありますか?

解決しようとしている問題が\u0000またはを送信する方法である場合は、DOM に挿入する\u000Bに、アプリケーション固有のエンコーディングを String に適用する必要があります。もう一方の端では、同等のデコードを展開する必要があります。

解決しようとしている問題が、手遅れになる前に不良データを検出する方法である場合は、シリアライザーと最終出力ストリームの間に出力ストリーム フィルターを使用してこれを行うことができます。しかし、問題を検出した場合、それを修正する良い (つまり、XML コンシューマに対して透過的な) 方法はありません。

于 2012-10-08T10:42:45.403 に答える