8.13. XML 类型

xml数据类型可以用于存储XML数据。 将XML数据存到text类型中的优势在于它能够为结构良好性来检查输入值, 并且还支持函数对其进行类型安全性检查,可参阅Section 9.14。 要使用这个数据类型,编译时必须使用configure --with-libxml

xml可以存储由XML标准定义的格式良好的"文档", 以及由XML标准中的XMLDecl? content定义的"内容"片段, 大致上,这意味着内容片段可以有多个顶级元素或字符节点。 _xmlvalue_ IS DOCUMENT 表达式可以用来判断一个特定的xml值是一个完整的文件还是内容片段。

8.13.1. 创建XML值

使用函数xmlparse: 来从字符数据产生xml类型的值:

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)验证。

使用函数xmlserialize: 来从xml产生一个字符串。

XMLSERIALIZE ( { DOCUMENT | CONTENT } _value_ AS _type_ )

_type_可以是charactercharacter varyingtext(或其中某个的变种)。同时,根据SQL标准, 这是xml和字符类型之间的唯一的转换方式,但PostgreSQL仍支持简单的值转换。

当一个字符串值在没有通过XMLPARSEXMLSERIALIZE的情况下, 与xml类型进行转换时,分别的,选择DOCUMENTCONTENT 是由"XML option" 会话配置参数决定,这个配置参数可以由标准命令来设置:

SET XML OPTION { DOCUMENT | CONTENT };

或更多类似的PostgreSQL语法:

SET xmloption TO { DOCUMENT | CONTENT };

默认是CONTENT,因此所有的XML数据格式都能支持。

Note: 随着默认XML选项的设置,如果字符串中包含一个文档类型声明, 那么你不能直接将其转换成xml类型,因为XML内容片断的定义不支持。 如果非得需要这么做,要么使用XMLPARSE,要么更改XML选项。

8.13.2. 编码处理

在对客户端和服务器端进行多字符编码,以及在通过它们传递XML数据时需要格外注意。 当使用文本模式(正常模式)在服务器端和客户端之间传递查询和查询结果时, PostgreSQL在各自终端对所有传递的字符数据和字符编码进行相互转换,参阅Section 22.3。 这包括XML值的字符串表示形式,如上面的例子。这通常意味着XML数据中的编码声明, 在客户端和服务器之间传递时,可以成为无效字符数据转换为其他编码。 这是因为枚举编码声明没有改变。为了应对该问题, 提交输入到xml 类型的字符串中的编码声明会被ignored, 同时,内容会被认为是在当前服务器编码中。所以,对正确的处理来说, XML数据的字符串必须从在当前客户端编码中的客户端发送。客户端有责任, 要么在传递到服务器之前将文档转换成当前客户端编码,要么适当的调整客户端编码。 输出时,xml类型的值不会有编码声明, 同时客户端会认为所有的数据都是在当前客户端编码之中的。

当使用二进制模式在服务器和客户端之间传递查询参数和查询结果,没有执行字符集转换, 因此解决方法是不同的。在这种情况下,将会遵守XML数据中的编码声明, 并且如果声明不存在,数据会被假定为UTF-8格式(如同XML标准要求那样, 但需要注意的是PostgreSQL不支持UTF-16)。输出时,会对数据进行编码声明以指定客户端编码, 除非客户端编码格式是UTF-8。

不用说,如果XML数据编码格式,客户端编码格式,以及服务器编码格式都一样, 那么用PostgreSQL处理XML数据将会减少错误,并且效率会很高。在内部, XML数据是用UTF-8编码格式处理的,因此,如果服务器端编码也是UTF-8时,计算性能会很高。

Caution
当服务器编码非UTF-8格式时,一些XML相关的函数可能完全不支持非ASCII数据, 特别是xpath() 函数。

8.13.3. 访问XML值

xml数据类型有些特殊,因为它不提供比较运算符。这是因为对XML数据, 没有很好的定义和通用的比较运算符。这样做的一个后果是, 不能通过xml与检索值的比较来检索行。因此XML值必须带有一个单独的关键值, 如一个ID。另一个解决比较XML值的方法是,先将它们转换成字符串, 但需要注意的是字符串比较与一个有用的XML比较方法无关。

因为没有针对xml数据类型的比较运算符,因此不能在这种类型的字段上直接创建索引。 如果需要对XML数据进行快速搜索,可能的解决方法包括将表达式转换成一个字符串类型, 然后对它进行索引,或索引一个XPath表达式。当然,实际查询是不得不进行调整, 以使用一个索引表达式进行检索。

PostgreSQL中的文本检索功能也可用于加快XML数据的全文搜索。 但必要的预处理支持在PostgreSQL中还不能获得。