受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: devel

8.13. XML类型 #

xml 数据类型可用于存储 XML 数据。与把 XML 数据存储在 text 字段中相比,它的优势在于会检查输入值是否格式 良好,并且提供了可执行类型安全操作的支持函数;见 Section 9.15。使用该数据类型要求安装时启用 configure --with-libxml

xml 类型既可以存储符合 XML 标准定义的格式良好的 文档,也可以存储 内容 片段;后者是参照 XQuery 和 XPath 数据模型中更宽松的 document node 概念来定义的。粗略地说,这意味着内容片段可以拥有多个顶层元素或字符 节点。表达式 xmlvalue IS DOCUMENT 可用于判断某个特定的 xml 值是完整文档,还是仅仅是一个 内容片段。

关于 xml 数据类型的限制和兼容性说明,见 Section D.3

8.13.1. 创建XML值 #

要从字符数据生成 xml 类型的值,可以使用函数 xmlparse

XMLPARSE ( { DOCUMENT | CONTENT } value)

示例:

XMLPARSE (DOCUMENT '<?xml version="1.0"?><book><title>Manual</title><chapter>...</chapter></book>')
XMLPARSE (CONTENT 'abc<foo>bar</foo><bar>foo</bar>')

按照 SQL 标准,这是把字符串转换为 XML 值的 唯一方法;但 PostgreSQL 特有的下列语法:

xml '<foo>bar</foo>'
'<foo>bar</foo>'::xml

也可以使用。

即使输入值指定了文档类型声明(DTD),xml 类型也不会 根据 DTD 来验证输入值。 目前也没有内置支持可依据其他 XML 模式语言(如 XML Schema) 来执行验证。

反向操作,也就是从 xml 生成字符串值,则使用函数 xmlserialize

XMLSERIALIZE ( { DOCUMENT | CONTENT } value AS type [ [ NO ] INDENT ] )

type 可以是 charactercharacter varyingtext(或它们的别名)。同样,根据 SQL 标准,这是在 xml 与字符类型之间进行转换的唯一方式,但 PostgreSQL 也允许你直接进行类型转换。

INDENT 选项会让结果以美化格式输出,而 NO INDENT(默认值)则只输出原始输入字符串。 直接转换为字符类型时,也会得到原始字符串。

当字符串值在不经过 XMLPARSEXMLSERIALIZE 的情况下与 xml 类型互相转换时, 选择 DOCUMENT 还是 CONTENT 由会话配置参数 XML option 决定,可以使用 标准命令设置:

SET XML OPTION { DOCUMENT | CONTENT };

或使用更接近 PostgreSQL 风格的语法

SET xmloption TO { DOCUMENT | CONTENT };

默认值是 CONTENT,因此允许所有形式的 XML 数据。

8.13.2. 编码处理 #

在客户端、服务器以及其间传输的 XML 数据上处理多字符编码时, 必须格外小心。使用文本模式向服务器发送查询并把查询结果返回给 客户端时,PostgreSQL 会将客户端与 服务器之间传输的所有字符数据转换为目标端的字符编码,参见 Section 23.3。这也包括表示 XML 值的字符串,如上例 所示。这通常意味着,由于字符数据在客户端和服务器之间传输时可能被 转换为其他编码,XML 数据中包含的编码声明可能会失效,因为内嵌的 编码声明本身并不会被修改。为处理这种情况,表示 xml 类型输入值的字符串中所包含的编码声明会被 忽略,其内容被假定为当前服务器编码。随后, 为了正确处理,客户端发出的 XML 数据字符串必须采用当前客户端编码。 客户端负责在将文档发送给服务器之前把它们转换为当前客户端编码, 或适当调整客户端编码。输出时,xml 类型值不会带有 编码声明,而客户端会假定所有数据都采用当前客户端编码。

若使用二进制模式把查询参数传给服务器并把查询结果返回客户端, 则不会执行编码转换,因此情况有所不同。在这种情况下,XML 数据中的 编码声明会被识别;如果缺少编码声明,则该数据会被假定为 UTF-8 (由于 XML 标准的要求,请注意 PostgreSQL 不支持 UTF-16)。 输出时,除非客户端编码是 UTF-8(此时编码声明会被省略),否则 数据会带有一个指明客户端编码的编码声明。

不言而喻,在 PostgreSQL 中处理 XML 数据时,如果 XML 数据编码、客户端编码和服务器编码三者相同, 不仅更高效,也更不容易出错。由于 XML 数据在内部以 UTF-8 处理, 如果服务器编码也是 UTF-8,则处理效率最高。

Caution

当服务器编码不是 UTF-8 时,某些与 XML 相关的函数在非 ASCII 数据上可能完全无法工作。尤其是 xmltable()xpath(),这是一个已知问题。

8.13.3. 访问XML值 #

xml 数据类型有些特殊,因为它不提供任何比较操作符。 这是因为对 XML 数据并不存在良定义且通用的比较算法。其结果是, 你无法通过把某个 xml 值与搜索值比较来检索行。 因此,XML 值通常应伴随一个独立的键字段,例如 ID。另一种比较 XML 值的办法,是先把它们转换成字符串;但请注意,字符串比较对 XML 的比较需求通常帮助不大。

由于 xml 数据类型没有可用的比较操作符,因此无法直接 在这种类型上创建索引。如果需要在 XML 中快速搜索,可行方案包括: 将表达式转换为字符串类型后为其建立索引,或者为某个 XPath 表达式 建立索引。当然,实际查询也必须相应调整为使用该被索引的表达式。

PostgreSQL 的文本搜索功能也可用于加速 XML 数据的全文搜索。不过,目前 PostgreSQL 发行版中仍缺少所需的 预处理支持。

提交更正

如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。