内部に 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
の間にバイナリも含まれているため、非整列化中に次のエラーが発生します。A
B
41 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も参照)。
私の質問:
JAXB/DOM API が、読み戻せない無効なXML ドキュメントの作成を許可するのはなぜですか? マーシャリング中に高速で失敗するべきではありませんか?
エレガントでグローバルなソリューションはありますか?私は人々がこの問題に次のように取り組んでいるのを見ました:
しかし、Java の成熟した XML スタック (私は 1.7.0_05 を使用しています) は、デフォルトで、または簡単な設定でこれを処理するべきではありませんか? エスケープ、無視、または迅速な失敗を探していますが、無効な XML を生成するデフォルトの動作は受け入れられません。このような基本的な機能は、クライアント側で追加のコーディングを必要とすべきではないと考えています。