Вопрос

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

ОБНОВЛЯТЬ:Я получил это, работая с База64 класс из библиотека кодеков Apache Commons, на случай, если кто-нибудь еще попытается сделать что-то подобное.

Это было полезно?

Решение

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

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

Другие советы

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 подобен насилию: если он не решает вашу проблему, значит, вы недостаточно его используете.

РЕДАКТИРОВАТЬ:

КСТАТИ:Base64 + CDATA, вероятно, лучшее решение.

(РЕДАКТИРОВАТЬ2:
Тот, кто обновит меня, пожалуйста, обновите и настоящий ответ.Мы не хотим, чтобы какой-нибудь бедняга пришел сюда и реализовал мой метод, потому что он имел самый высокий рейтинг в SO, верно?)

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

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

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

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

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

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

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

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

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


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

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

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

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

Вы также можете Uuencode вы исходные двоичные данные.Этот формат немного старше, но он выполняет то же самое, что и кодировка base63.

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

Традиционным решением этой проблемы является архив (например,смола).Но если вы хотите сохранить вложенный документ в текстовом формате или у вас нет доступа к библиотеке архивирования файлов, существует также стандартизированная схема, которая широко используется в электронной почте и HTTP: multipart/* MIME с Кодирование передачи контента:двоичный.

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

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

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

Но здесь есть накладные расходы на base64.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top