MySQL 5.0:以(格式良好的)XML格式输出BLOB数据?

时间:2009-07-06 23:49:52

标签: mysql xml formatting hex blob

我正在为MySQL编写一个Web界面,它执行一些查询并返回一些带有查询结果的XML数据。现在,运行查询的表有三个LONGBLOB列(用于存储图像数据等)。

但是,当我尝试解析XML时,我遇到了BLOB列中某些字符的问题:看起来MySQL只是将直接十六进制数据转储到流中,而我的解析器不接受它。 / p>

有没有办法让MySQL输出结构良好的XML包含十六进制数据?我查看了mysqldump --hex-blob选项,但我正在使用mysql程序,因为我需要对表运行查询,而不仅仅是获取整个表的内容。我可以使用字符串表示形式,xs:hexBinary标记中的<field>元素或任何类似的元素。

编辑:我在PHP 5.2.9中工作。该问题的背景是提供一种类似Digg的API,其具有多个HTTP可访问的端点,例如, /objects/edit等等。我们的想法是,跨多个平台的许多客户端应用程序可以使用API​​作为访问同一数据集的共同基础,而无需关心支持它的数据库(可能会发生变化)。

我存储的一个对象类型是(小)图像,我想使用MySQL LONGBLOB类型直接在数据库中这样做。 (我只负责使API与MySQL后端数据库一起工作,所以答案可以将数据库类型,语言和实用程序作为数字。)基本上我要做的是找到一种方法来提供图像与其他混合类型数据(主要是字符串)相同的XML文档中的请求应用程序。

编辑:我使用mysql --xml命令行程序和PHP passthru函数的组合将MySQL从MySQL中取出。这是在我开发它的时候完成我想要的最简单的方法;有没有更好的办法?我应该从MySQL字段构建PHP中的XML而不是依赖MySQL来为我做这件事吗?如果是这样,那会更容易在XML中发送图像数据吗?

3 个答案:

答案 0 :(得分:3)

您无法将直接二进制数据放入XML文档中。如果将任何在编码中有效的字符(可能是UTF-8)放在XML文档中(如果将其放在CDATA部分中)(并且它不会包含字符串“&lt;![CDATA [”),则可以放置)原始二进制数据中包含无效的UTF-8序列。您需要将二进制数据转换为某种文本表示形式。

使用xs:hexBinary格式(即[0-9A-F] {2})将为二进制数据的每个字节产生2个字符(字节)。

使用Base64编码每3个字节的数据使用4个字符(2 ^ 8/2 ^ 6),因此它是一种更有效的格式。不幸的是,从MySQL执行此操作是messy,因此最好以二进制格式从MySQL中提取数据并将其编码到Web应用程序中的Base64中。

编辑:SO似乎解析了CDATA部分。我在“!”周围添加了空格。使其停止解析并激活格式化。

编辑:

在不了解您正在做什么的情况下,让我概述一种方法:

// ... setup and exec query...
while ($row = mysql_fetch_assoc($rs)) {
    print('<item>');
    print('<date>' . $row['date'] . '</date>');
    // ... etc. ...
    // more efficient to use mysql_result but this is simpler
    $img = $row['image'];
    print('<image>' . base64_encode($img) . '</image>');
    // CDATA is *probably* not needed
    print('<image><![CDATA[' . base64_encode($img) . ']]></image>');
    // or, if you decide you want hex format anyway...
    print('<image>' . unpack('H*', $img) . '</image>');
}

这应该产生严格有效的XML。想想看,你现在拥有的十六进制数据在XML中应该没问题。您使用的解析器是什么?

答案 1 :(得分:0)

XML不支持直接存储二进制数据,使用Base64编码

答案 2 :(得分:0)

它可能会使UTF8编码图像更容易,并且如果您执行了mysql查询并在php中构建了xml,它也会使您的网站响应更快...... Fork&amp;执行是昂贵的操作......

您可以使用simpleXml并执行以下操作:

$myxml->addChild('imageBlob', base64_encode($mysql_row['imageBlob']));