可以使用 xml
数据类型来存储 XML 数据。它比在 text
字段中存储 XML 数据的优势在于,它检查输入值的格式是否正确,并且有支持函数对其执行类型安全操作;请参阅 第 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
也可以使用。
xml
类型不会根据文档类型声明 (DTD) 验证输入值,即使输入值指定了 DTD 也是如此。目前也没有内置支持来验证其他 XML 模式语言,例如 XML 模式。
逆操作(从 xml
生成字符串值)使用函数 xmlserialize
:
XMLSERIALIZE ( { DOCUMENT | CONTENT }value
AStype
[ [ NO ] INDENT ] )
type
可以是 character
、character varying
或 text
(或其中一个的别名)。同样,根据 SQL 标准,这是在类型 xml
和字符类型之间进行转换的唯一方法,但 PostgreSQL 还允许您简单地强制转换该值。
INDENT
选项导致结果以美观格式打印,而 NO INDENT
(这是默认值)仅发出原始输入字符串。强制转换为字符类型同样会生成原始字符串。
当字符字符串值强制转换为类型 xml
或从类型 xml
强制转换时,分别不经过 XMLPARSE
或 XMLSERIALIZE
,DOCUMENT
与 CONTENT
的选择由 “XML 选项” 会话配置参数决定,该参数可以使用标准命令设置
SET XML OPTION { DOCUMENT | CONTENT };
或更类似 PostgreSQL 的语法
SET xmloption TO { DOCUMENT | CONTENT };
默认值为 CONTENT
,因此允许所有形式的 XML 数据。
在处理客户端、服务器以及通过它们传递的 XML 数据上的多个字符编码时,必须小心。在使用文本模式将查询传递到服务器并将查询结果传递到客户端(这是正常模式)时,PostgreSQL 会将客户端和服务器之间传递的所有字符数据以及反之转换为各自终端的字符编码;请参见 第 24.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 发行版中提供。