112

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

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

4

12 に答える 12

225

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

XML ドキュメントでのバイナリ データの処理

于 2008-08-21T13:37:58.600 に答える
216

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は暴力のようなものです-問題が解決しない場合は、XMLを十分に使用していません。

編集:

ところで:Base64+CDATAはおそらく最良のソリューションです

( EDIT2:
私をアップモッドする人は誰でも、本当の答えもアップモッドしてください。SOで最高ランクだったので、貧しい魂がここに来て実際に私のメソッドを実装することは望んでいませんよね?)

于 2008-08-21T13:46:32.620 に答える
28

Base64 は確かに正しい答えですが、CDATA はそうではありません。基本的には、「これは何でもかまいません」と言っていますが、単なるものであってはなら、Base64 でエンコードされたバイナリ データでなければなりません。XML スキーマは、 Base 64 バイナリをxsd で使用できるプリミティブ データ型として定義します。

于 2008-08-21T17:44:17.730 に答える
15

先週、この問題が発生しました。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>
于 2010-08-03T21:35:11.657 に答える
6

私は通常、バイナリ データをMIME Base64またはURL エンコーディングでエンコードします。

于 2008-08-21T13:38:36.773 に答える
5

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

于 2008-08-21T13:37:52.580 に答える
4

他の答えはほとんど問題ありませんが、yEncのような別のよりスペース効率の良いエンコーディング方法を試すことができます。(yEnc wikipediaリンク)yEncを使用すると、「箱から出してすぐに」チェックサム機能も利用できます。以下のリンクを読んでください。もちろん、XMLにはネイティブのyEncタイプがないため、エンコードされたノードを適切に記述するためにXMLスキーマを更新する必要があります。

理由:エンコード戦略base64 / 63により、uuencodeetal。エンコーディングにより、保存および転送する必要のあるデータ(オーバーヘッド)の量が約40%増加します(yEncの1〜2%に対して)。エンコードする内容によっては、40%のオーバーヘッドが問題になる可能性があります。


yEnc-ウィキペディアの要約: https ://en.wikipedia.org/wiki/YEnc yEncは、Usenetまたは電子メールのメッセージでバイナリファイルを転送するためのバイナリからテキストへのエンコードスキームです。... uuencodeやBase64などの以前のエンコード方法に対するyEncの追加の利点は、デコードされたファイルが完全に配信されたことを確認するためのCRCチェックサムが含まれていることです。</ p>

于 2012-02-17T10:01:12.987 に答える
4

バイナリからテキストへのエンコーディングはすべてうまくいきます。私はそのようなものを使用します

<data encoding="yEnc>
<![CDATA[ encoded binary data ]]>
</data>
于 2010-07-01T08:31:40.913 に答える
4

おそらくそれらを既知のセットにエンコードします-base 64のようなものが一般的な選択です.

于 2008-08-21T13:37:19.727 に答える
2

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

于 2008-08-31T16:52:05.217 に答える
0

XML 形式を制御できる場合は、問題を裏返しにする必要があります。バイナリー XML を添付するのではなく、複数のパーツ (そのうちの 1 つに XML が含まれる) を持つ文書を囲む方法を検討する必要があります。

これに対する従来の解決策は、アーカイブ (tar など) です。ただし、同封のドキュメントをテキストベースの形式で保持したい場合、またはファイル アーカイブ ライブラリにアクセスできない場合は、電子メールと HTTP で多用される標準化されたスキームもあります。これはmultipart/* MIME with Content-Transfer-Encoding: バイナリ.

たとえば、サーバーが 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 はcid、Content-Id ヘッダーへの識別子である URI スキームを使用して、囲んでいるマルチパート内のバイナリ データを参照します。このスキームのオーバーヘッドは、MIME ヘッダーだけです。HTTP 応答にも同様のスキームを使用できます。もちろん、HTTP プロトコルでは、マルチパート ドキュメントを個別の要求/応答に送信するオプションもあります。

マルチパートでデータをラップしたくない場合は、データ URI を使用します。

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

しかし、これにはbase64のオーバーヘッドがあります。

于 2014-12-10T08:42:35.403 に答える