Frage

Ich habe zwei in Java geschriebene Anwendungen, die über XML-Nachrichten über das Netzwerk miteinander kommunizieren.Ich verwende auf der Empfängerseite einen SAX-Parser, um die Daten aus den Nachrichten zurückzugewinnen.Eine der Anforderungen besteht darin, Binärdaten in eine XML-Nachricht einzubetten, aber SAX gefällt das nicht.Weiß jemand, wie man das macht?

AKTUALISIEREN:Ich habe das mit dem zum Laufen gebracht Base64 Klasse aus der Apache Commons Codec-Bibliothek, falls jemand anderes etwas Ähnliches versucht.

War es hilfreich?

Lösung

Sie könnten die Binärdaten mit Base64 kodieren und in ein Base64-Element einfügen;Der folgende Artikel ist ziemlich gut zu diesem Thema.

Umgang mit Binärdaten in XML-Dokumenten

Andere Tipps

XML ist so vielseitig...

<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 ist wie Gewalt – Wenn es Ihr Problem nicht löst, verwenden Sie nicht genug davon.

BEARBEITEN:

Übrigens:Base64 + CDATA ist wahrscheinlich die beste Lösung

(EDIT2:
Wer auch immer mich aktualisiert, bitte aktualisiert auch die echte Antwort.Wir wollen nicht, dass irgendeine arme Seele hierherkommt und meine Methode tatsächlich umsetzt, weil sie auf SO die höchste Bewertung hatte, oder?)

Base64 ist in der Tat die richtige Antwort, CDATA jedoch nicht. Das bedeutet im Grunde:„das könnte alles sein“, aber es muss nicht kann einfach alles sein, es müssen Base64-codierte Binärdaten sein.XML-Schema definiert Basis-64-Binärdatei als primitiver Datentyp die Sie in Ihrem XSD verwenden können.

Ich hatte dieses Problem erst letzte Woche.Ich musste eine PDF-Datei serialisieren und sie in einer XML-Datei an einen Server senden.

Wenn Sie .NET verwenden, können Sie eine Binärdatei direkt in einen Base64-String konvertieren und ihn in ein XML-Element einfügen.

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

Oder es gibt eine Methode, die direkt in das XmlWriter-Objekt integriert ist.In meinem speziellen Fall musste ich den Datentyp-Namespace von Microsoft einschließen:

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();

Die Zeichenfolge abc sieht etwa so aus:

<?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>

Normalerweise kodiere ich die Binärdaten mit MIME Base64 oder URL-Kodierung.

Versuchen Sie, Ihre Binärdaten mit Base64 zu kodieren/dekodieren.Schauen Sie sich auch die CDATA-Abschnitte an

Codieren Sie sie vielleicht in einen bekannten Satz – so etwas wie Basis 64 ist eine beliebte Wahl.

Beliebig Binär-zu-Text-Kodierung wird den Zweck erfüllen.Ich benutze so etwas

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

Während die anderen Antworten größtenteils in Ordnung sind, können Sie eine andere, platzsparendere Kodierungsmethode wie yEnc ausprobieren.(yEnc Wikipedia-Link) Mit yEnc erhalten Sie auch sofort eine Prüfsummenfunktion.Lesen und Links unten.Da XML keinen nativen yEnc-Typ hat, sollte Ihr XML-Schema natürlich aktualisiert werden, um den codierten Knoten richtig zu beschreiben.

Warum:Aufgrund der Kodierungsstrategien base64/63, uuencode et al.Codierungen erhöhen die Datenmenge (Overhead), die Sie speichern und übertragen müssen, um etwa 40 % (vs.yEnc's 1-2 %).Je nachdem, was Sie kodieren, könnten 40 % Overhead ein Problem sein/werden.


yEnc – Wikipedia-Zusammenfassung: https://en.wikipedia.org/wiki/YEncyEnc ist ein Binär-zu-Text-Kodierungsschema zur Übertragung von Binärdateien in Nachrichten im Usenet oder per E-Mail....Ein zusätzlicher Vorteil von yEnc gegenüber früheren Kodierungsmethoden wie uuencode und Base64 ist die Einbeziehung einer CRC-Prüfsumme, um zu überprüfen, ob die dekodierte Datei intakt geliefert wurde.‎

Der Base64-Overhead beträgt 33 %.

BaseXML für XML1.0 Der Overhead beträgt nur 20 %.Aber es ist kein Standard und es gibt bisher nur eine C-Implementierung.Probieren Sie es aus, wenn Sie sich Gedanken über die Datengröße machen.Beachten Sie, dass Browser jedoch dazu neigen, die Komprimierung so zu implementieren, dass sie weniger benötigt wird.

Ich habe es nach der Diskussion in diesem Thread entwickelt: Binärdaten in XML kodieren:Alternativen zu base64.

Du kannst auch Uuencode Sie ursprüngliche Binärdaten.Dieses Format ist etwas älter, macht aber dasselbe wie die Base63-Kodierung.

Wenn Sie das XML-Format beherrschen, sollten Sie das Problem auf den Kopf stellen.Anstatt das binäre XML anzuhängen, sollten Sie darüber nachdenken, wie Sie ein Dokument einschließen, das aus mehreren Teilen besteht, von denen einer XML enthält.

Die traditionelle Lösung hierfür ist ein Archiv (z. B.Teer).Wenn Sie Ihr beiliegendes Dokument jedoch in einem textbasierten Format aufbewahren möchten oder keinen Zugriff auf eine Dateiarchivierungsbibliothek haben, gibt es auch ein standardisiertes Schema, das häufig in E-Mails und HTTP verwendet wird multipart/* MIME mit Content-Transfer-Encoding:binär.

Wenn Ihre Server beispielsweise über HTTP kommunizieren und Sie ein mehrteiliges Dokument senden möchten, wobei das primäre Dokument ein XML-Dokument ist, das auf Binärdaten verweist, könnte die HTTP-Kommunikation etwa so aussehen:

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--

Wie im obigen Beispiel verweist das XML auf die Binärdaten im umschließenden Multipart, indem es a verwendet cid URI-Schema, das eine Kennung für den Content-Id-Header darstellt.Der Overhead dieses Schemas wäre nur der MIME-Header.Ein ähnliches Schema kann auch für HTTP-Antworten verwendet werden.Natürlich haben Sie im HTTP-Protokoll auch die Möglichkeit, ein mehrteiliges Dokument in separate Anfragen/Antworten zu senden.

Wenn Sie vermeiden möchten, dass Ihre Daten mehrteilig sind, verwenden Sie den Daten-URI:

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

Dies hat jedoch den Base64-Overhead.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top