可以使用 xml
数据类型存储 XML 数据。与将 XML 数据存储在 text
字段中的优势在于它检查输入值的格式是否正确,并且有支持函数对其进行类型安全的运算;请参见 第 9.15 节。使用此数据类型需要安装时使用 configure --with-libxml
构建。
xml
类型可以存储格式良好的 “文档”,如 XML 标准定义的那样,以及 “内容” 片段,这些片段通过引用更宽松的 “文档节点” 来定义,该节点由 XQuery 和 XPath 数据模型定义。大致而言,这意味着内容片段可以拥有多个顶级元素或字符节点。表达式
可用于评估特定 xmlvalue
IS DOCUMENTxml
值是完整文档还是仅内容片段。
可以在 第 D.3 节 中找到 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 Schema。
反向操作,从 xml
生成字符字符串值,使用 xmlserialize
函数:
XMLSERIALIZE ( { DOCUMENT | CONTENT }value
AStype
[ [ NO ] INDENT ] )
type
可以是 character
、character varying
或 text
(或这些类型的别名)。同样,根据 SQL 标准,这是在 xml
类型和字符类型之间进行转换的唯一方法,但 PostgreSQL 还允许您简单地将值进行强制转换。
INDENT
选项会导致结果被格式化,而 NO INDENT
(默认值)只发出原始输入字符串。强制转换为字符类型也会产生原始字符串。
当字符字符串值在不通过 XMLPARSE
或 XMLSERIALIZE
的情况下强制转换为 xml
类型或从 xml
类型强制转换时,DOCUMENT
与 CONTENT
的选择由 “XML 选项” 会话配置参数决定,可以使用标准命令设置该参数
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 发行版中尚未提供必要的预处理支持。
如果您在文档中发现任何不正确的内容、与您对特定功能的体验不符或需要进一步说明,请使用 此表格 报告文档问题。