支持的版本:当前 (17) / 16 / 15 / 14 / 13
开发版本:devel
不支持的版本:12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2

8.13. XML类型 #

xml 数据类型可用于存储 XML 数据。它优于将 XML 数据存储在 text 字段中的优势在于,它会检查输入值是否格式良好,并且有支持函数对其执行类型安全的操作;请参见第 9.15 节。使用此数据类型需要安装时使用 configure --with-libxml 构建。

xml 类型可以存储格式良好的 文档,如 XML 标准所定义,以及 内容片段,这些片段通过参考 XQuery 和 XPath 数据模型中更宽松的 文档节点 来定义。粗略地说,这意味着内容片段可以有多个顶级元素或字符节点。表达式 xmlvalue IS DOCUMENT 可用于评估特定的 xml 值是完整文档还是仅内容片段。

有关 xml 数据类型的限制和兼容性说明,请参见 第 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

xml 类型不会针对文档类型声明 (DTD)验证输入值,即使输入值指定了 DTD。当前也没有内置支持来针对其他 XML 模式语言(例如 XML 模式)进行验证。

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

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

type 可以是 charactercharacter varyingtext(或其中一个的别名)。同样,根据 SQL 标准,这是在 xml 类型和字符类型之间进行转换的唯一方法,但 PostgreSQL 也允许您简单地转换该值。

INDENT 选项会导致结果以美观格式打印,而 NO INDENT(默认设置)仅发出原始输入字符串。转换为字符类型也会生成原始字符串。

当字符值在不经过 XMLPARSEXMLSERIALIZE 的情况下转换为 xml 类型时,选择 DOCUMENT 还是 CONTENTXML 选项会话配置参数决定,该参数可以使用标准命令设置

SET XML OPTION { DOCUMENT | CONTENT };

或更像 PostgreSQL 的语法

SET xmloption TO { DOCUMENT | CONTENT };

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

8.13.2. 编码处理 #

在客户端、服务器和通过它们的 XML 数据中处理多种字符编码时必须小心。当使用文本模式将查询传递到服务器并将查询结果传递给客户端时(这是正常模式),PostgreSQL 会将客户端和服务器之间传递的所有字符数据转换为相应端的字符编码,反之亦然;请参见第 23.3 节。这包括 XML 值的字符串表示形式,例如在上述示例中。这通常意味着 XML 数据中包含的编码声明可能会失效,因为当字符数据在客户端和服务器之间传输时会转换为其他编码,因为嵌入的编码声明不会更改。为了应对此行为,输入到 xml 类型的字符串中包含的编码声明会被忽略,并且假定内容采用当前服务器编码。因此,为了正确处理,XML 数据的字符串必须以当前客户端编码从客户端发送。客户端有责任在将文档发送到服务器之前将其转换为当前客户端编码,或者适当地调整客户端编码。在输出时,xml 类型的值将没有编码声明,客户端应假定所有数据都采用当前客户端编码。

当使用二进制模式将查询参数传递到服务器并将查询结果返回给客户端时,不会执行编码转换,因此情况有所不同。在这种情况下,将观察 XML 数据中的编码声明,如果不存在,则假定数据采用 UTF-8 编码(XML 标准要求;请注意 PostgreSQL 不支持 UTF-16)。在输出时,数据将具有指定客户端编码的编码声明,除非客户端编码为 UTF-8,在这种情况下将省略该声明。

毋庸置疑,如果 XML 数据编码、客户端编码和服务器编码相同,则使用 PostgreSQL 处理 XML 数据将更少出错且效率更高。由于 XML 数据在内部以 UTF-8 处理,如果服务器编码也为 UTF-8,则计算效率最高。

注意

当服务器编码不是 UTF-8 时,某些 XML 相关函数可能完全无法处理非 ASCII 数据。已知 xmltable()xpath() 尤其存在此问题。

8.13.3. 访问 XML 值 #

xml 数据类型是不寻常的,因为它不提供任何比较运算符。这是因为没有为 XML 数据定义良好且普遍有用的比较算法。这样做的一个结果是,您无法通过将 xml 列与搜索值进行比较来检索行。因此,XML 值通常应附带单独的键字段,例如 ID。比较 XML 值的另一种解决方案是先将它们转换为字符串,但请注意,字符串比较与有用的 XML 比较方法几乎无关。

由于 xml 数据类型没有比较运算符,因此无法直接在此类型的列上创建索引。如果需要快速搜索 XML 数据,可能的解决方法包括将表达式转换为字符串类型并对其进行索引,或对 XPath 表达式进行索引。当然,必须调整实际查询以按索引表达式进行搜索。

PostgreSQL 中的文本搜索功能也可用于加速 XML 数据的全文搜索。但是,必要的预处理支持尚未在 PostgreSQL 发行版中提供。

提交更正

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