2

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

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

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

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

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

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

4

3 回答 3

3

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

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

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

编辑:所以似乎解析了 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 中应该没问题。你用的是什么解析器?

于 2009-07-13T17:49:55.420 回答
0

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

于 2009-07-12T00:17:09.417 回答
0

它可能会使 UTF8 编码图像更容易,并且如果您执行 mysql 查询并在 php 中构建 xml,它也会使您的站点更具响应性...... Fork 和 exec 是昂贵的操作......

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

$myxml->addChild('imageBlob', base64_encode($mysql_row['imageBlob']));
于 2009-07-16T05:46:19.387 回答