ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# 8.13\. XML 类型 `xml`数据类型可以用于存储XML数据。 将XML数据存到`text`类型中的优势在于它能够为结构良好性来检查输入值, 并且还支持函数对其进行类型安全性检查,可参阅[Section 9.14](#calibre_link-1459)。 要使用这个数据类型,编译时必须使用`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_`可以是`character`,`character varying` 或`text`(或其中某个的变种)。同时,根据SQL标准, 这是`xml`和字符类型之间的唯一的转换方式,但PostgreSQL仍支持简单的值转换。 当一个字符串值在没有通过`XMLPARSE`或`XMLSERIALIZE`的情况下, 与`xml`类型进行转换时,分别的,选择`DOCUMENT`与`CONTENT` 是由"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](#calibre_link-1272)。 这包括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中还不能获得。