2008-08-21 27 views
95

私はJavaで書かれた2つのアプリケーションを持っていて、ネットワーク上でXMLメッセージを使って互いに通信します。受信側でSAXパーサーを使用して、メッセージからデータを取り戻しています。要件の1つは、バイナリデータをXMLメッセージに埋め込むことですが、SAXはこれを好まないのです。誰もこれを行う方法を知っていますか?バイナリデータをXMLにどのように埋め込むのですか?

更新:apache commons codec libraryBase64クラスでこれを動作させました。他の誰かが同様のことを試している場合に備えて。

+3

Genius!ちょうど私が探していたもの! –

答えて

192

2進データをbase64でエンコードしてBase64要素に入れることができます。以下の記事は、この件に関するかなり良い記事です。

Handling Binary Data in XML Documents

+0

「=」文字が存在すると、一部のファイアウォール(https接続)が時々ブロックされるように見えます。 (文字列の多くのエンコーディングは、 "kdiLKjdfdilfse ="のような結果になります) – tObi

4

おそらく、それらを既知のセットにエンコードすることができます。ベース64のようなものが一般的な選択です。

5

バイナリデータのBase64エンコード/デコードを試してください。また、CDATAセクションも見てください

190

XMLはとても汎用性があります...

<DATA> 
    <BINARY> 
    <BIT index="0">0</BIT> 
    <BIT index="1">0</BIT> 
    <BIT index="2">1</BIT> 
    ... 
    <BIT index="n">1</BIT> 
    </BINARY> 
</DATA> 

XMLは暴力のようなものです - それはあなたの問題が解決しない場合、あなたはそれを十分に使用していません。

EDIT:ところで

:Base64で+ CDATAは、おそらく最良の解決策

(EDIT2です:私をupmods誰
、また本当の答えをupmodしてください私たちはどんな貧しい魂が来てほしくありません。

+0

私はちょうど私の友人にその引用を繰り返し、そして彼が笑った後、彼は "とあなたに指示された場合は痛いです" :) – kaybenleroll

+5

これは何でもですあなたが深刻な場合は、XMLの完全に不名誉な使用です。そしてもしあなたがいないのであれば、初心者はレベルが高くないと思う人は知っていますか? –

+1

Jeremy ...若い23歳の若者のために、あなたはひどく深刻です/文字通り...これはなぜ、これがなぜラインの間の勇者のための警告的な物語で面白い答えであるかを見るために業界で十分長く働いていません。 – Kev

22

Base64は確かに正しい答えですが、CDATAは基本的には「これは何でもよい」と言われていますが、ではなくでなければなりません。ちょうど何であれ、そうでなければならないBase64でエンコードされたバイナリデータ。 XMLスキーマはxsdで使用できるBase 64 binary as a primitive datatypeを定義しています。

+1

'xs:base64Binary'データ型に言及するための余分なポイント。これは正しいタイプです。 –

2

Uuencode元のバイナリデータもあります。この形式は少し古いですが、base63エンコーディングと同じことを行います。

3

binary-to-text encodingはこのトリックを行います。私はちょうど先週、この問題を抱えている

<data encoding="yEnc> 
<![CDATA[ encoded binary data ]]> 
</data> 
9

のようなものを使用します。私は、PDFファイルをシリアライズして、XMLファイル内でサーバーに送信しなければなりませんでした。

.NETを使用している場合は、バイナリファイルを直接base64文字列に変換し、XML要素内に置くことができます。

string base64 = Convert.ToBase64String(File.ReadAllBytes(fileName)); 

または、XmlWriterオブジェクトに組み込まれたメソッドがあります。私の特定のケースでは、私は、Microsoftのデータ型の名前空間を含める必要がありました:

StringBuilder sb = new StringBuilder(); 
System.Xml.XmlWriter xw = XmlWriter.Create(sb); 
xw.WriteStartElement("doc"); 
xw.WriteStartElement("serialized_binary"); 
xw.WriteAttributeString("types", "dt", "urn:schemas-microsoft-com:datatypes", "bin.base64"); 
byte[] b = File.ReadAllBytes(fileName); 
xw.WriteBase64(b, 0, b.Length); 
xw.WriteEndElement(); 
xw.WriteEndElement(); 
string abc = sb.ToString(); 

文字列abcはこのようなものになります。

<?xml version="1.0" encoding="utf-16"?> 
<doc> 
    <serialized_binary types:dt="bin.base64" xmlns:types="urn:schemas-microsoft-com:datatypes"> 
     JVBERi0xLjMKJaqrrK0KNCAwIG9iago8PCAvVHlwZSAvSW5mbw...(plus lots more) 
    </serialized_binary> 
</doc> 
0

ここで続行する方法の良い例だがXEP-0239

PS:Mo's answerを読むことを忘れないでください。

PS2:XEPの「注意」セクションをお読みください。

2

Base64エンコーディングを使用しないでください。格納するデータ量が40%以上増加するため、このコードは使用しないでください。むしろ、yEncのような他のエンコーディングメソッドを使用してください。

+1

@Jamineだから、他の選択肢がありますか? – Hunt

3

Base64オーバーヘッドは33%です。

BaseXML(XML1.0)オーバーヘッドはわずか20%です。しかし、これは標準ではなく、まだC実装しかありません。データサイズに関心がある場合はそれを確認してください。ただし、ブラウザは、圧縮が必要ではないように圧縮を実装する傾向があることに注意してください。

このスレッドのディスカッションの後に、Encoding binary data within XML : alternatives to base64と書いてあります。

0

XML形式を支配している場合は、問題を解決する必要があります。バイナリXMLを添付するのではなく、XMLを含む複数の部分を持つドキュメントを囲む方法について考える必要があります。

伝統的な解決策は、アーカイブ(例:tar)です。しかし、あなたの文書をテキスト形式で保存したい場合や、ファイルアーカイブライブラリにアクセスできない場合は、電子メールとHTTPで頻繁に使用される標準化スキーム(multipart/* MIMEContent-Transfer-Encoding: binary)があります。

例えば

サーバーがHTTPを介して通信し、マルチパート文書を送信したい場合は、バイナリデータを参照するXMLドキュメントであることの主は、HTTP通信は次のようになります。

POST/HTTP/1.1 
Content-Type: multipart/related; boundary="qd43hdi34udh34id344" 
... other headers elided ... 

--qd43hdi34udh34id344 
Content-Type: application/xml 

<myxml> 
    <data href="cid:data.bin"/> 
</myxml> 
--qd43hdi34udh34id344 
Content-Id: <data.bin> 
Content-type: application/octet-stream 
Content-Transfer-Encoding: binary 

... binary data ... 
--qd43hdi34udh34id344-- 

上記の例のように、XMLは、Content-Idヘッダーの識別子であるcid URIスキームを使用して、包括的なマルチパート内のバイナリデータを参照します。このスキームのオーバヘッドはMIMEヘッダーだけです。同様の方式をHTTP応答に使用することもできます。もちろん、HTTPプロトコルでは、マルチパート文書を別の要求/応答に送るオプションもあります。

あなたはマルチパートであなたのデータをラップ回避したい場合、データURIを使用することです:

<myxml> 
    <data href="data:application/something;charset=utf-8;base64,dGVzdGRhdGE="/> 
</myxml> 

をしかし、これは、base64のオーバーヘッドを持っています。

関連する問題