Как вы встраиваете двоичные данные в XML? - PullRequest
103 голосов
/ 21 августа 2008

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

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

Ответы [ 12 ]

210 голосов
/ 21 августа 2008

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

Обработка двоичных данных в документах XML

209 голосов
/ 21 августа 2008

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

25 голосов
/ 21 августа 2008

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

12 голосов
/ 04 августа 2010

У меня была эта проблема только на прошлой неделе. Мне пришлось сериализовать 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>
6 голосов
/ 21 августа 2008

Я обычно кодирую двоичные данные с помощью MIME Base64 или Кодировка URL .

5 голосов
/ 21 августа 2008

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

4 голосов
/ 17 февраля 2012

Хотя остальные ответы в основном хороши, вы можете попробовать другой, более экономичный способ кодирования, например, yEnc. ( yEnc wikipedia link ) С yEnc также получите возможность контрольной суммы прямо "из коробки". Читайте и ссылки ниже. Конечно, поскольку XML не имеет собственного типа yEnc, ваша XML-схема должна быть обновлена ​​для правильного описания закодированного узла.

Почему : Из-за стратегий кодирования base64 / 63, uuencode et al. Кодировки увеличивают объем данных (накладные расходы), которые необходимо хранить и передавать, примерно на 40% (по сравнению с 1-2% у yEnc). В зависимости от того, что вы кодируете, 40% накладных расходов может стать проблемой.


yEnc - Аннотация Википедии: https://en.wikipedia.org/wiki/YEnc yEnc - это схема кодирования двоичного текста для передачи двоичных файлов в сообщениях в Usenet или по электронной почте. ... Дополнительным преимуществом yEnc перед предыдущими методами кодирования, такими как uuencode и Base64, является включение контрольной суммы CRC для проверки того, что декодированный файл был доставлен без изменений.

4 голосов
/ 01 июля 2010

Любое двоичное-текстовое кодирование сделает свое дело. Я использую что-то подобное

<data encoding="yEnc>
<![CDATA[ encoded binary data ]]>
</data>
4 голосов
/ 21 августа 2008

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

3 голосов
/ 05 июля 2013

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

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

Я разработал его после обсуждения в этой теме: Кодирование двоичных данных в XML: альтернативы base64 .

...