Как вы вставляете двоичные данные в XML?


95

У меня есть два приложения, написанные на Java, которые обмениваются данными друг с другом с помощью XML-сообщений по сети. Я использую SAX-парсер на принимающей стороне, чтобы получить данные обратно из сообщений. Одним из требований является встраивание двоичных данных в XML-сообщение, но SAX это не нравится. Кто-нибудь знает как это сделать?

ОБНОВЛЕНИЕ: Я получил эту работу с классом Base64 от apache commons codec library, в случае, если кто-то пытается что-то подобное.

+3

Genius! Только то, что я искал! 02 фев. 092009-02-02 10:23:29

192

Вы можете кодировать двоичные данные с помощью base64 и поместить его в элемент Base64; нижеследующая статья является довольно хорошей на эту тему.

Handling Binary Data in XML Documents

  0

Позаботьтесь, некоторые брандмауэры (https-соединения) иногда блокируются, когда присутствует символ «=». (Многие кодировки строки приводят к чему-то вроде «kdiLKjdfdilfse =») 25 мар. 152015-03-25 08:20:41


4

Возможно, кодировать их в известный набор - что-то вроде базы 64 является популярным выбором.


5

Попробуйте Base64 кодировать/декодировать ваши двоичные данные. Также смотрите разделы CDATA


6

Я обычно кодировать двоичные данные с MIME Base64 или URL encoding.


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 реального ответа Мы не хотим, бедняжки прийти здесь и на самом деле реализовать мой метод, потому что он был самым высоким на SO, правильно?)

  0

Я только что повторил эту цитату моему другу, и после того, как он засмеялся, он сказал: «И это больно, если на вас направлены» :) 26 сен. 082008-09-26 16:58:40

+5

Это не что иное, как совершенно бесчестное использование XML, если вы серьезно. А если нет, то как начинающие, которые не пишут на высоком уровне-думаю-низкого уровня, знают? 02 фев. 092009-02-02 10:59:05

+1

Джереми ...для молодого 23-летнего парня вы ужасно серьезны/буквальны ... вы явно недостаточно долго работали в отрасли, чтобы понять, почему это забавный ответ с предостерегающей сказкой для смелых между линиями. 02 фев. 092009-02-02 11:53:30

+1

Я бы предположил, что они будут знать: 1) насколько отличается этот ответ от большого зеленого выше, с двойным голосом, и 2), читая остальную часть темы, где другие указывают, насколько смешной шутка. 02 фев. 092009-02-02 15:54:34

+9

@Mike - вы бы подумали, что .... SO быстро становится питательной средой для юмористических юмористических молодых педантов. 02 фев. 092009-02-02 18:44:26

  0

Я думаю, это смешно. Но да, еще раз, использование фактического базового типа данных - путь. CData слишком общий. 21 июл. 092009-07-21 18:48:17

  0

+1 для размещения зеркала для всех тех консультантов, которые думают, что XML = золотой молот, lol. Btw, I LOVE xml, но только если используется правильно. 01 июл. 102010-07-01 08:35:12

  0

Смеялся громко, показал всем моим друзьям. -1 к ненавистникам! 21 сен. 102010-09-21 23:11:58

+9

Является ли это MS Office XML ??? 07 янв. 112011-01-07 01:19:15

+2

Я не думаю, что это достаточно описательно - возможно, следует использовать «BINARYDIGIT», а не сокращение «BIT»? ;-) 08 апр. 112011-04-08 09:48:07

  0

Приходите на вас, беззастенчивые gits .... облегчите. Это был ранний ответ, прежде чем мы все узнали SO ettiquette ... :) 02 фев. 092009-02-02 10:53:15

  0

Да, но он не заслуживает того, чтобы оценивать как ответ «2-го лучшего». Это вводит в заблуждение. 02 фев. 092009-02-02 10:57:04

  0

Так почему же меня вниз? 02 фев. 092009-02-02 11:45:15

  0

И это вряд ли оскорбительно ... пожалуйста, перезагрузите юмористический юмор/модуль жизни. 02 фев. 092009-02-02 11:47:45

  0

@ (кто бы ни опустил [Mo] (http://stackoverflow.com/questions/19893/how-do-you-embed-binary-data-in-xml#19939)): Осветите немного, это было весело (как код, так и подсказку). +1 21 авг. 082008-08-21 14:06:04

  0

Да, правильно, поэтому нам нравится оценивать шутки как лучшие ответы? Где ушло наше чувство логики? 02 фев. 092009-02-02 10:57:46

  0

Где наше чувство юмора испарилось? Это был закрытый вопрос с бета-версиями ... тогда некоторая свобода была разрешена. Повторно вставьте модуль юмора. 02 фев. 092009-02-02 13:39:34

  0

Ничего себе. Это приведет к тому, что средний файл в килобайтах будет примерно в 230 раз больше :) 08 авг. 112011-08-08 12:03:58

+29

О, для f *** s sake. Это была шутка. Что я сделал?!: Http://thedailywtf.com/Articles/The-HomanReadable-Encryption-Key.aspx 18 сен. 112011-09-18 18:11:36

+1

Мне это нравится! лучший юмор кодирования. 22 сен. 112011-09-22 13:16:08

+1

+1. Веселое! :) 25 сен. 112011-09-25 14:41:27

  0

Может быть, edit2 должен быть отклонением от аванса, сверху, головой. EDIT опущена только для того, чтобы получить более отдаленный от самого высокого рейтинга. 18 июл. 142014-07-18 10:25:48

  0

Аналогия особенно интересна. «XML, насилие межбарьерных данных xchange» ... 18 июл. 142014-07-18 10:27:45

  0

LOL. Я должен сам это реализовать 11 янв. 172017-01-11 17:26:34

  0

Я думаю, что очень интересно, что после всех этих лет в этом шуточном ответе остается больше всего голосов. Возможно, это показывает, что существует реальная разница в значениях пользователей S.O., которые голосуют за ответы, и модераторы, которые в наши дни зажимают малейший намек на легкомыслие или отсутствие серьезности. 12 янв. 172017-01-12 04:17:03


22

Base64 действительно правильный ответ, но CDATA не является, это в основном говорит: «это может быть что угодно», однако оно должно быть не быть просто чем угодно, это должно быть Бинарные данные с кодировкой Base64. XML-схема определяет Base 64 binary as a primitive datatype, которую вы можете использовать в xsd.

+1

Дополнительная информация для указания типа данных 'xs: base64Binary', который является правильным типом. 08 дек. 172017-12-08 21:21:14


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

Строка а выглядит то, что выглядит следующим образом:

<?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, у вас есть альтернатива? 20 мар. 142014-03-20 16:40:00


3

Накладные расходы Base64 составляют 33%.

BaseXML для XML1.0 накладные расходы составляют только 20%. Но это не стандарт и только реализация C. Проверьте это, если вы заинтересованы в размере данных. Обратите внимание, что браузеры, как правило, используют сжатие, так что он менее необходим.

Я разработал его после обсуждения в этой теме: Encoding binary data within XML : alternatives to base64.


0

Если у вас есть контроль над XML-форматом, вы должны решить проблему наизнанку. Вместо того, чтобы прикреплять бинарный XML, вы должны подумать о том, как заключить документ с несколькими частями, один из которых содержит XML.

Традиционное решение для этого - архив (например, tar). Но если вы хотите сохранить прилагаемый документ в текстовом формате или если у вас нет доступа к библиотеке архивирования файлов, также существует стандартизованная схема, которая используется в основном по электронной почте и HTTP, которая равна multipart/* MIME с Content-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 ссылается на двоичные данные в охватывающем multipart, используя схему URI cid, которая является идентификатором заголовка Content-Id. Накладные расходы этой схемы будут только заголовком MIME. Аналогичную схему можно также использовать для ответа HTTP. Конечно, в протоколе HTTP вы также можете отправить многостраничный документ в отдельный запрос/ответ.

Если вы хотите, чтобы избежать упаковки данных в многоголосных является использование данных URI:

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

Но это имеет накладные расходы base64.