8.13. XML类型

xml数据类型可以用于存储XML数据。相比较将XML数据存到text类型中,xml数据类型的优势在于 它能够为XML的编排良好性来检查输入值,并且还支持函数对其进行类型安全性检查,可参阅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)

Examples:

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

can also be used.

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.2。 这包括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中还不能获得。 然后