¿Cómo incrusta datos binarios en XML?


95

Tengo dos aplicaciones escritas en Java que se comunican entre sí utilizando mensajes XML a través de la red. Estoy usando un analizador SAX en el extremo receptor para recuperar los datos de los mensajes. Uno de los requisitos es incrustar datos binarios en un mensaje XML, pero a SAX no le gusta esto. ¿Alguien sabe como hacer esto?

ACTUALIZACIÓN: Esto funcionó con la clase Base64 del apache commons codec library, en caso de que alguien más esté intentando algo similar.

+3

Genius! ¡Justo lo que estaba buscando! 02 feb. 092009-02-02 10:23:29

192

Puede codificar los datos binarios usando base64 y ponerlos en un elemento Base64; el siguiente artículo es bastante bueno sobre el tema.

Handling Binary Data in XML Documents

  0

Tenga cuidado, algunos cortafuegos (https-connections) parecen bloquear algunas veces cuando el carácter "=" está presente. (Muchas codificaciones de cadena dan como resultado algo así como "kdiLKjdfdilfse =") 25 mar. 152015-03-25 08:20:41


4

Quizás codificarlos en un conjunto conocido, algo así como base 64 es una opción popular.


5

Pruebe Base64 codificando/decodificando sus datos binarios. Consulte también las secciones CDATA


6

lo general codificar los datos binarios con MIME Base64 o URL encoding.


190

XML es tan versátil ...

<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 es como violencia - Si no se soluciona el problema, no se está usando bastante de él.

EDIT:

Por cierto: Base 64 + CDATA es probablemente la mejor solución

(Edit2:.
El que me upmods, por favor, también upmod la verdadera respuesta No queremos que cualquier pobre alma para venir aquí y realmente implementar mi método porque fue el más alto en SO, ¿verdad?)

  0

Acabo de repetir esa cita a mi amigo, y después de que él se riera, dijo "y es doloroso si se dirige a ti" :) 26 sep. 082008-09-26 16:58:40

+5

Esto no es más que un uso completamente vergonzoso de XML si habla en serio. Y si no lo eres, ¿cómo lo sabrían los principiantes que no escriben-nivel alto-pensar-bajo-nivel? 02 feb. 092009-02-02 10:59:05

+1

Jeremy ...para un muchacho joven de 23 años, eres tremendamente serio/literal ... claramente no has trabajado lo suficiente en la industria para ver por qué esta es una respuesta divertida con un cuento de advertencia para los valientes entre líneas. 02 feb. 092009-02-02 11:53:30

+1

Supongo que sabrían por 1) qué tan diferente es esta respuesta del gran verde anterior con el doble de votos, y 2) leyendo el resto del hilo donde otros señalan qué gracioso es el chiste. 02 feb. 092009-02-02 15:54:34

+9

@Mike - hubieras pensado que ... ASÍ QUE se está convirtiendo rápidamente en un caldo de cultivo para los pedantes ególatras sin sentido del humor. 02 feb. 092009-02-02 18:44:26

  0

Creo que es gracioso. Pero sí, una vez más, usar el tipo de datos base64 es el camino a seguir. CData es demasiado genérico. 21 jul. 092009-07-21 18:48:17

  0

+1 por poner un espejo para todos aquellos consultores que piensan XML = golden hammer, lol. Por cierto, ME ENCANTA xml, pero solo si se usa correctamente. 01 jul. 102010-07-01 08:35:12

  0

Ríe en voz alta, se lo mostré a todos mis amigos. -1 a los enemigos! 21 sep. 102010-09-21 23:11:58

+9

¿Es este MS Office XML ??? 07 ene. 112011-01-07 01:19:15

+2

No creo que sea lo suficientemente descriptivo. ¿Quizás debería usar 'BINARYDIGIT' en lugar de la contracción 'BIT'? ;-) 08 abr. 112011-04-08 09:48:07

  0

Vamos gits sin humor .... aligerar. Esta fue una respuesta temprana antes de que todos supiéramos SO ettiquette ... :) 02 feb. 092009-02-02 10:53:15

  0

Sí, pero no merece clasificarse como la "segunda mejor respuesta". Eso es engañoso. 02 feb. 092009-02-02 10:57:04

  0

Entonces, ¿por qué me downvote? 02 feb. 092009-02-02 11:45:15

  0

Y no es ofensivo ... reinicie el humor humor/módulo de vida. 02 feb. 092009-02-02 11:47:45

  0

@ (quien haya modificado [Mo] (http://stackoverflow.com/questions/19893/how-do-you-embed-binary-data-in-xml#19939)): aligere un poco, eso fue gracioso (tanto el código como la broma). +1 21 ago. 082008-08-21 14:06:04

  0

Sí, claro, ¿nos gusta clasificar las bromas como las mejores respuestas? ¿Dónde ha desaparecido nuestro sentido de la lógica? 02 feb. 092009-02-02 10:57:46

  0

¿Dónde se evaporó nuestro sentido del humor? Esta fue una pregunta cerrada de días beta ... se permitió cierto margen de acción en ese momento. Por favor, vuelva a insertar el módulo de humor. 02 feb. 092009-02-02 13:39:34

  0

Wow. Esto hará que el archivo de rango promedio de kilobytes sea 230 veces más grande :) 08 ago. 112011-08-08 12:03:58

+29

Oh por el bien de f ***. Esto fue una broma. ¡Qué hice?!: Http://thedailywtf.com/Articles/The-HumanReadable-Encryption-Key.aspx 18 sep. 112011-09-18 18:11:36

+1

¡Amo esto! el mejor humor de codificación 22 sep. 112011-09-22 13:16:08

+1

+1. ¡Divertidísimo! :) 25 sep. 112011-09-25 14:41:27

  0

Tal vez edit2 debe ser un descargo de responsabilidad por adelantado, en la parte superior, la cabeza. EDITAR downvoted únicamente para obtenerlo más lejos del más alto clasificado. 18 jul. 142014-07-18 10:25:48

  0

Sin embargo, la analogía es particularmente interesante. "XML, la violencia de datos inter-barrera xchange" ... 18 jul. 142014-07-18 10:27:45

  0

LOL. Tengo que implementar esto yo mismo 11 ene. 172017-01-11 17:26:34

  0

Creo que es muy interesante que después de todos estos años esta respuesta de broma todavía tenga la mayoría de los votos. Quizás muestra que hay una diferencia real en los valores de los usuarios de S.O., que votan por las respuestas, y los moderadores que en estos días reprimen el más mínimo indicio de ligereza o falta de seriedad. 12 ene. 172017-01-12 04:17:03


22

Base64 es de hecho la respuesta correcta, pero CDATA no lo es, eso es básicamente decir: "esto podría ser cualquier cosa", sin embargo debe no ser cualquier cosa, tiene que ser Base64 datos binarios codificados. XML Schema define Base 64 binary as a primitive datatype que puede usar en su xsd.

+1

Punto extra para mencionar el tipo de datos 'xs: base64Binary', que es el tipo correcto de usar. 08 dic. 172017-12-08 21:21:14


2

También puede Uuencode sus datos binarios originales. Este formato es un poco más antiguo pero hace lo mismo que la codificación base63.


3

Cualquier binary-to-text encoding hará el truco. Uso algo así

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

9

Tuve este problema la semana pasada. Tuve que serializar un archivo PDF y enviarlo, dentro de un archivo XML, a un servidor.

Si está utilizando .NET, puede convertir un archivo binario directamente en una cadena base64 y pegarlo dentro de un elemento XML.

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

O, hay un método integrado en el objeto XmlWriter.En mi caso particular, he tenido que incluir espacio de nombres de tipo de datos de 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 cadena abc se ve algo que se parece a esto:

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

He aquí un buen ejemplo de cómo proceder XEP-0239

PD: no olvides leer Mo's answer.

PS2: lea la sección NOTICE en el XEP.


2

No utilice la codificación base64 ya que aumenta la cantidad de datos que necesita almacenar al menos un 40%. Más bien use otros métodos de codificación como yEnc.

+1

@Jamine, ¿tienes alguna otra alternativa? 20 mar. 142014-03-20 16:40:00


3

La sobrecarga de Base64 es del 33%.

BaseXML para XML1.0 la sobrecarga es solo 20%. Pero no es un estándar y solo tiene una implementación C todavía. Compruébelo si le preocupa el tamaño de los datos. Sin embargo, tenga en cuenta que los navegadores tienden a implementar la compresión para que sea menos necesaria.

Lo desarrollé después de la discusión en este hilo: Encoding binary data within XML : alternatives to base64.


0

Si tiene control sobre el formato XML, debe volver el problema al revés. En lugar de adjuntar el XML binario, debe pensar en cómo adjuntar un documento que tiene varias partes, una de las cuales contiene XML.

La solución tradicional para esto es un archivo (por ejemplo, tar). Pero si desea conservar el documento adjunto en un formato de texto o si no tiene acceso a una biblioteca de archivado de archivos, también hay un esquema estandarizado que se usa mucho en correo electrónico y HTTP que es multipart/* MIME con Content-Transfer-Encoding: binary.

Por ejemplo, si sus servidores se comunican a través de HTTP y desea enviar un documento de varias partes, siendo un documento XML que se refiere a un conjunto de datos binarios de la primaria, la comunicación HTTP podría ser algo como esto:

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

Como en el ejemplo anterior, el XML se refiere a los datos binarios en la multiparte adjunta utilizando un esquema de URI cid que es un identificador del encabezado Content-Id. La sobrecarga de este esquema sería solo el encabezado MIME. Un esquema similar también se puede usar para la respuesta HTTP. Por supuesto, en el protocolo HTTP, también tiene la opción de enviar un documento de varias partes en una solicitud/respuesta por separado.

Si se quiere evitar de embalar sus datos en una multiparte es utilizar los datos URI:

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

Pero esto tiene la sobrecarga de base 64.