2025年9月25日: PostgreSQL 18 发布!
支持的版本:当前 (18) / 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 数据。与在 text 字段中存储 XML 数据相比,它的优点在于它会检查输入值的格式是否正确,并且支持函数来执行类型安全的对该数据的操作;参见 第 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 Schema 等其他 XML 模式语言进行验证。

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

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

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

INDENT 选项会使结果进行美化打印,而 NO INDENT(这是默认值)仅输出原始输入字符串。转换为字符类型同样会产生原始字符串。

当字符字符串值在不经过 XMLPARSEXMLSERIALIZE 的情况下转换为 xml 类型或从 xml 类型转换时,DOCUMENTCONTENT 的选择由 XML 选项 会话配置参数决定,该参数可以使用标准命令进行设置

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,在这种情况下将省略。

Needless to say, processing XML data with PostgreSQL will be less error-prone and more efficient if the XML data encoding, client encoding, and server encoding are the same. Since XML data is internally processed in UTF-8, computations will be most efficient if the server encoding is also 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 分发版中尚未提供必要的预处理支持。

提交更正

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