Pergunta

Tenho dois aplicativos escritos em Java que se comunicam usando mensagens XML pela rede.Estou usando um analisador SAX no receptor para recuperar os dados das mensagens.Um dos requisitos é incorporar dados binários em uma mensagem XML, mas o SAX não gosta disso.Alguém sabe como fazer isso?

ATUALIZAR:Eu consegui isso trabalhando com o Base64 aula do biblioteca de codecs apache commons, caso alguém esteja tentando algo semelhante.

Foi útil?

Solução

Você poderia codificar os dados binários usando base64 e colocá-los em um elemento Base64;o artigo abaixo é muito bom sobre o assunto.

Tratamento de dados binários em documentos XML

Outras dicas

XML é tão 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 é como violência - se não resolver seu problema, você não está usando o suficiente.

EDITAR:

POR FALAR NISSO:Base64 + CDATA é provavelmente a melhor solução

(EDITAR2:
Quem quer que me atualize, por favor atualize também a resposta real.Não queremos que nenhuma pobre alma venha aqui e realmente implemente meu método porque ele foi o mais bem classificado no SO, certo?)

Base64 é de fato a resposta certa, mas CDATA não, basicamente dizendo:"isso pode ser qualquer coisa", porém deve não seja qualquer coisa, devem ser dados binários codificados em Base64.Esquema XML define Binário base 64 como um tipo de dados primitivo que você pode usar no seu xsd.

Eu tive esse problema na semana passada.Tive que serializar um arquivo PDF e enviá-lo, dentro de um arquivo XML, para um servidor.

Se estiver usando .NET, você pode converter um arquivo binário diretamente em uma string base64 e colá-lo dentro de um elemento XML.

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

Ou existe um método embutido no objeto XmlWriter.No meu caso específico, tive que incluir o namespace do tipo de dados da 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();

A string abc se parece com isto:

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

Eu normalmente codifico os dados binários com MIMEBase64 ou Codificação de URL.

Experimente codificar/decodificar Base64 seus dados binários.Veja também as seções CDATA

Talvez codifique-os em um conjunto conhecido - algo como base 64 é uma escolha popular.

Qualquer codificação binária para texto fará o truque.Eu uso algo assim

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

Embora as outras respostas sejam geralmente boas, você pode tentar outro método de codificação com mais eficiência de espaço, como yEnc.(link da Wikipédia yEnc) Com o yEnc, você também obtém o recurso de soma de verificação "pronto para usar".Leia e links abaixo.Obviamente, como o XML não possui um tipo yEnc nativo, seu esquema XML deve ser atualizado para descrever corretamente o nó codificado.

Por que:Devido às estratégias de codificação base64/63, uuencode et al.As codificações aumentam a quantidade de dados (overhead) que você precisa armazenar e transferir em aproximadamente 40% (vs.yEnc é 1-2%).Dependendo do que você está codificando, uma sobrecarga de 40% pode ser/se tornar um problema.


yEnc - Resumo da Wikipédia: https://en.wikipedia.org/wiki/YEncyEnc é um esquema de codificação binário para texto para transferência de arquivos binários em mensagens na Usenet ou via e-mail....Uma vantagem adicional do yEnc em relação aos métodos de codificação anteriores, como uuencode e Base64, é a inclusão de uma soma de verificação CRC para verificar se o arquivo decodificado foi entregue intacto.‎

A sobrecarga de Base64 é de 33%.

BaseXML para XML1.0 a sobrecarga é de apenas 20%.Mas ainda não é um padrão e só possui uma implementação em C.Verifique se você está preocupado com o tamanho dos dados.Observe que, no entanto, os navegadores tendem a implementar a compactação para que ela seja menos necessária.

Eu o desenvolvi após a discussão neste tópico: Codificando dados binários em XML:alternativas para base64.

Você também pode Uuencode seus dados binários originais.Este formato é um pouco mais antigo, mas faz a mesma coisa que a codificação base63.

Se você tiver controle sobre o formato XML, deverá virar o problema do avesso.Em vez de anexar o XML binário, você deve pensar em como incluir um documento que possui múltiplas partes, uma das quais contém XML.

A solução tradicional para isso é um arquivo (por exemplo,alcatrão).Mas se você quiser manter o documento anexo em um formato baseado em texto ou se não tiver acesso a uma biblioteca de arquivamento de arquivos, há também um esquema padronizado que é muito usado em e-mail e HTTP, que é multiparte/* MIME com Codificação de transferência de conteúdo:binário.

Por exemplo, se seus servidores se comunicam através de HTTP e você deseja enviar um documento multipartes, sendo o principal um documento XML que se refere a dados binários, a comunicação HTTP pode ser mais ou menos assim:

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 no exemplo acima, o XML refere-se aos dados binários na multiparte envolvente usando um cid Esquema URI que é um identificador para o cabeçalho Content-Id.A sobrecarga deste esquema seria apenas o cabeçalho MIME.Um esquema semelhante também pode ser usado para resposta HTTP.É claro que no protocolo HTTP, você também tem a opção de enviar um documento multipartes em solicitação/resposta separada.

Se você quiser evitar agrupar seus dados em uma multiparte, use o URI de dados:

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

Mas isso tem sobrecarga de base64.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top