Come si incorporano dati binari in XML?


95

Ho due applicazioni scritte in Java che comunicano tra loro tramite messaggi XML sulla rete. Sto usando un parser SAX dal lato ricevente per recuperare i dati dai messaggi. Uno dei requisiti è quello di incorporare dati binari in un messaggio XML, ma SAX non gli piace. Qualcuno sa come fare questo?

AGGIORNAMENTO: Ho funzionato con la classe Base64 da apache commons codec library, nel caso in cui qualcun altro stia tentando qualcosa di simile.

+3

Genius! Proprio quello che stavo cercando! 02 feb. 092009-02-02 10:23:29

192

Puoi codificare i dati binari usando base64 e inserirli in un elemento Base64; l'articolo che segue è piuttosto buono sull'argomento.

Handling Binary Data in XML Documents

  0

Attenzione, alcuni firewall (https-connessioni) sembrano a volte bloccarsi quando è presente il carattere "=". (Molte codifiche di string si traducono in qualcosa del genere "kdiLKjdfdilfse =") 25 mar. 152015-03-25 08:20:41


4

Forse li codifichi in un set noto, qualcosa come la base 64 è una scelta popolare.


5

Prova Base64 codifica/decodifica i dati binari. Vedi anche le sezioni CDATA


6

Io di solito codificare i dati binari con MIME Base64 o URL encoding.


190

XML è così versatile ...

<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 è come la violenza - Se non risolve il problema, non lo si utilizza abbastanza.

EDIT:

BTW: Base64 + CDATA è probabilmente la soluzione migliore

(EDIT2:.
Chiunque mi upmods, si prega anche upmod la vera risposta Non vogliamo alcun povera anima a venire qui ed effettivamente implementare il mio metodo perché era il più alto in classifica su SO, giusto?)

  0

Ho appena ripetuto quella citazione al mio amico, e dopo aver riso, ha detto "ed è doloroso se diretto a te" :) 26 set. 082008-09-26 16:58:40

+5

Questo è niente di meno che un uso assolutamente vergognoso dell'XML se sei serio. E se non lo sei, come potrebbero sapere i principianti che non scrivono-alto-livello-di-basso-livello? 02 feb. 092009-02-02 10:59:05

+1

Jeremy ...per un giovane ragazzo di 23 anni sei terribilmente serio/letterale ... chiaramente non hai lavorato abbastanza a lungo nel settore per capire perché questa è una risposta divertente con un ammonimento per i coraggiosi tra le righe. 02 feb. 092009-02-02 11:53:30

+1

Suppongo che saprebbero di 1) quanto è diversa questa risposta dal grande verde in alto con il doppio dei voti, e 2) leggendo il resto del thread dove altri sottolineano quanto sia divertente la battuta. 02 feb. 092009-02-02 15:54:34

+9

@Mike - avresti pensato che ... SO sta rapidamente diventando un terreno fertile per i giovani pedanti senza umorismo. 02 feb. 092009-02-02 18:44:26

  0

Penso che sia divertente. Ma sì, ancora una volta, usare il datapype base64 attuale è la strada da percorrere. CData è troppo generico. 21 lug. 092009-07-21 18:48:17

  0

+1 per mettere su uno specchio per tutti quei consulenti che pensano XML = martello d'oro, lol. Btw, I LOVE xml, ma solo se usato correttamente. 01 lug. 102010-07-01 08:35:12

  0

Ridendo ad alta voce, ha mostrato a tutti i miei amici. -1 agli odiatori! 21 set. 102010-09-21 23:11:58

+9

Questo MS Office XML ??? 07 gen. 112011-01-07 01:19:15

+2

Non penso che sia abbastanza descrittivo - forse si dovrebbe usare "BINARYDIGIT" piuttosto che la contrazione "BIT"? ;-) 08 apr. 112011-04-08 09:48:07

  0

Vieni, git senza umorismo .... riduci. Questa è stata una risposta anticipata, prima che tutti noi imparassimo così i dettagli ... :) 02 feb. 092009-02-02 10:53:15

  0

Sì, ma non merita di classificarsi come la "seconda migliore" risposta. Questo è fuorviante. 02 feb. 092009-02-02 10:57:04

  0

Allora perché mi metti in votazione? 02 feb. 092009-02-02 11:45:15

  0

Ed è difficilmente offensivo ... per favore ri-boot humour humor/modulo vita. 02 feb. 092009-02-02 11:47:45

  0

@ (chi ha perso di testa [Mo] (http://stackoverflow.com/questions/19893/how-do-you-embed-binary-data-in-xml#19939)): Alleggeriti un po ', è stato divertente (sia il codice che la battuta). +1 21 ago. 082008-08-21 14:06:04

  0

Sì, giusto, quindi ci piace classificare le barzellette come le migliori risposte? Dov'è finito il nostro senso della logica? 02 feb. 092009-02-02 10:57:46

  0

Dov'è finito il senso dell'umorismo? Questa era una domanda a giorni in closed beta ... un po 'di margine era stato concesso a quei tempi. Si prega di reinserire il modulo umorismo. 02 feb. 092009-02-02 13:39:34

  0

Wow. Questo renderà il file della gamma dei kilobyte media circa 230 volte più grande :) 08 ago. 112011-08-08 12:03:58

+29

Oh per l'amor di dio. Questo era uno scherzo. Cosa ho fatto?!: Http://thedailywtf.com/Articles/The-HumanReadable-Encryption-Key.aspx 18 set. 112011-09-18 18:11:36

+1

Amo questo! il miglior umorismo codificante. 22 set. 112011-09-22 13:16:08

+1

+1. Divertente! :) 25 set. 112011-09-25 14:41:27

  0

Forse edit2 dovrebbe essere un disclaimer in anticipo, in cima, testa. EDIT downvoted esclusivamente per ottenere più lontano da quello più alto classificato. 18 lug. 142014-07-18 10:25:48

  0

L'analogia è particolarmente interessante, però. "XML, la violenza dei dati inter-barriera xchange" ... 18 lug. 142014-07-18 10:27:45

  0

LOL. Devo implementare questo me stesso 11 gen. 172017-01-11 17:26:34

  0

Penso che sia molto interessante che dopo tutti questi anni questa risposta di battuta abbia ancora il maggior numero di voti. Forse mostra che c'è una vera differenza nei valori degli utenti di S.O., che votano per le risposte, e dei moderatori che in questi giorni reprimono il minimo accenno di leggerezza o mancanza di serietà. 12 gen. 172017-01-12 04:17:03


22

Base64 è davvero la risposta giusta ma CDATA non lo è, questo in pratica dice: "questo potrebbe essere qualsiasi cosa", tuttavia deve non essere solo tutto, deve essere Dati binari codificati Base64. Lo schema XML definisce Base 64 binary as a primitive datatype che è possibile utilizzare in xsd.

+1

Punto extra per menzionare il tipo di dati 'xs: base64Binary', che è il tipo giusto da usare. 08 dic. 172017-12-08 21:21:14


2

È inoltre possibile Uuencode i dati binari originali. Questo formato è un po 'più vecchio ma fa la stessa cosa della codifica base63.


3

Qualsiasi binary-to-text encoding farà il trucco. Uso qualcosa del genere

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

9

Ho avuto questo problema solo la scorsa settimana. Ho dovuto serializzare un file PDF e inviarlo, all'interno di un file XML, a un server.

Se si utilizza .NET, è possibile convertire un file binario direttamente in una stringa base64 e inserirlo in un elemento XML.

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

Oppure, esiste un metodo integrato nell'oggetto XmlWriter.Nel mio caso particolare, ho dovuto includere tipo di dati dello spazio dei nomi di 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(); 

La stringa abc sembra qualcosa che assomiglia a questo:

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

Ecco un buon esempio di come procedere XEP-0239

PS: non dimenticare di leggere Mo's answer.

PS2: leggere la sezione AVVISO su XEP.


2

Non utilizzare la codifica Base64 in quanto aumenta la quantità di dati che è necessario memorizzare di almeno il 40%. Piuttosto usa altri metodi di codifica come yEnc.

+1

@Jamine quindi hai qualche altra alternativa? 20 mar. 142014-03-20 16:40:00


3

Base64 overhead è del 33%.

BaseXML per XML1.0 overhead è solo il 20%. Ma non è uno standard e ha ancora una implementazione C. Controllalo se sei preoccupato per la dimensione dei dati. Si noti che tuttavia i browser tendono ad implementare la compressione in modo che sia meno necessaria.

L'ho sviluppato dopo la discussione in questa discussione: Encoding binary data within XML : alternatives to base64.


0

Se si ha il controllo sul formato XML, è necessario capovolgere il problema. Piuttosto che collegare l'XML binario, dovresti pensare a come racchiudere un documento che ha più parti, una delle quali contiene XML.

La soluzione tradizionale è un archivio (ad es. Tar). Tuttavia, se si desidera conservare il documento allegato in un formato basato su testo o se non si ha accesso a una libreria di archiviazione file, esiste anche uno schema standardizzato che viene utilizzato pesantemente nelle e-mail e HTTP che è multipart/* MIME con Content-Transfer-Encoding: binary.

Per esempio, se i server comunicano tramite HTTP e si desidera inviare un documento in più parti, il principale è un documento XML che si riferisce a un insieme di dati binari, la comunicazione HTTP potrebbe essere simile a questa:

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

Come nell'esempio precedente, l'XML si riferisce ai dati binari nella multipartente che li include utilizzando uno schema URI cid che è un identificatore per l'intestazione Content-Id. Il sovraccarico di questo schema sarebbe solo l'intestazione MIME. Uno schema simile può essere utilizzato anche per la risposta HTTP. Ovviamente nel protocollo HTTP, hai anche la possibilità di inviare un documento multipart in richieste/risposte separate.

Se si vuole evitare di avvolgere i vostri dati in un multipart è quello di utilizzare i dati URI:

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

Ma questo ha l'overhead Base64.