xml
XML 数据
当前查看 PostgreSQL 18.6。
PG10–20 核心源码清单。类型转换与操作符类列出源码显式声明的关系;缺少记录不能排除通过其他机制进行转换或使用索引。
定义
XML 数据
xml
- 目录名称
- pg_catalog.xml
- 类型 OID
- 142
- 类型种类
- 基础类型
- 声明长度
- 变长(varlena)
- 存储策略
- 扩展
- 输入函数
- xml_in
- 输出函数
- xml_out
中文手册
阅读来源定义
8.13. XML类型
8.13. XML类型
xml 数据类型可用于存储 XML 数据。与把 XML 数据存储在 text 字段中相比,它的优势在于会检查输入值的良构性,并且提供了可执行类型安全操作的支持函数;见第 9.15 节。使用该数据类型要求构建时使用 configure --with-libxml。
xml 类型既可以存储 XML 标准所定义的良构“文档”,也可以存储“内容”片段;后者是参照 XQuery 和 XPath 数据模型中更宽松的“文档节点”概念来定义的。粗略地说,这意味着内容片段可以拥有多个顶层元素或字符节点。表达式 可用于判断某个特定的 xmlvalue IS DOCUMENTxml 值是完整文档,还是仅仅是一个内容片段。
关于 xml 数据类型的限制和兼容性说明,见第 D.3 节。
要从字符数据生成 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 可以是 character、character varying 或 text(或它们的别名)。同样,根据 SQL 标准,这是在 xml 与字符类型之间进行转换的唯一方式,但 PostgreSQL 也允许你直接进行类型转换。
INDENT 选项会让结果以美化格式输出,而 NO INDENT(默认值)则只输出原始输入字符串。直接转换为字符类型时,也会得到原始字符串。
如果将字符串转换为 xml 时未经过 XMLPARSE,或将 xml 转换为字符串时未经过 XMLSERIALIZE,则使用 DOCUMENT 还是 CONTENT 由“XML option”会话配置参数决定。此参数可通过以下标准命令设置:
SET XML OPTION { DOCUMENT | CONTENT };
或使用更接近 PostgreSQL 风格的语法
SET xmloption TO { DOCUMENT | CONTENT };
默认值是 CONTENT,因此允许所有形式的 XML 数据。
在客户端、服务器以及其间传输的 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() 尤其存在此问题。
xml 数据类型有些特殊,因为它不提供任何比较操作符。这是因为对 XML 数据并不存在良定义且通用的比较算法。其结果是,你无法通过把某个 xml 列与搜索值比较来检索行。因此,XML 值通常应伴随一个独立的键字段,例如 ID。另一种比较 XML 值的办法,是先把它们转换成字符串;但请注意,字符串比较对 XML 的比较需求通常帮助不大。
由于 xml 数据类型没有可用的比较操作符,因此无法直接在这种类型的列上创建索引。如果需要在 XML 中快速搜索,可行方案包括:将表达式转换为字符串类型后为其建立索引,或者为某个 XPath 表达式建立索引。当然,实际查询也必须相应调整为使用该被索引的表达式。
PostgreSQL 的文本检索功能也可用于加速 XML 数据的全文检索。不过,目前 PostgreSQL 发行版中仍缺少所需的预处理支持。
系统目录属性
此构建的源码初始化值。字段含义参见 pg_type 。包含头文件默认值;依赖构建的常量保留符号形式,不作为服务器运行时实测。
oid142descrXML contenttypacl_null_typlen-1typelem0typnamexmltypsendxml_sendtyptypebtypalignityparray0typbyvalftypdelim','typinputxml_intypmodin-typndims0typownerPOSTGREStyprelid0typmodout-typoutputxml_outtyptypmod-1typanalyze-typdefault_null_typnotnullftypreceivexml_recvtypstoragextypbasetype0typcategoryUtypcollation0typisdefinedttypnamespacepg_catalogtypsubscript-typdefaultbin_null_array_type_oid143typispreferredfarray_type_name_xml
类型转换 6
与此类型相关的显式 pg_cast 记录。PostgreSQL 还支持 pg_cast 之外的类型转换,缺少记录不能证明转换不可能。
版本比较
PostgreSQL 17.11 → 18.6。属性比较不包含构建标识和说明正文;原始目录字段与源描述保留原文。
这两个样本的系统目录和结构化属性没有变化。
这些构建的文档也有差异,请查看对应版本的手册定义。
文档与源码
- 构建
- 18.6 · https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2
- 指纹
555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f
相关条目
全部数据类型 · 下载此版本 JSON · 最早收录的样本不代表该类型的实际引入版本。