我有两个用Java编写的应用程序,它们使用网络上的XML消息进行通信。我在接收端使用SAX解析器来获取消息中的数据。其中一个要求是在XML消息中嵌入二进制数据,但SAX不支持此操作。请问是否有人知道如何实现?
更新:我使用apache commons codec库中的Base64类使其起作用,以防其他人尝试类似操作。
我有两个用Java编写的应用程序,它们使用网络上的XML消息进行通信。我在接收端使用SAX解析器来获取消息中的数据。其中一个要求是在XML消息中嵌入二进制数据,但SAX不支持此操作。请问是否有人知道如何实现?
更新:我使用apache commons codec库中的Base64类使其起作用,以防其他人尝试类似操作。
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 Schema将Base 64 binary定义为原始数据类型 ,您可以在xsd中使用它。
xs:base64Binary
数据类型,这是正确使用的数据类型。 - Christopher Schultz就在上周我也遇到了这个问题。我需要将一个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>
Base64的开销为33%。
BaseXML针对XML1.0的开销仅为20%。但它并不是一个标准,目前只有C语言实现。如果您关注数据大小,请查看一下。请注意,浏览器通常会实现压缩,因此这种方法不太需要。
在这个主题的讨论中,我开发了它:Encoding binary data within XML : alternatives to base64。