XML 类型

PostgreSQL 9.4.4 中文手册
上一页 | 上一级 | 章 8. 数据类型 | 下一页

# 8.13. XML 类型

`xml`数据类型可以用于存储XML数据。 将XML数据存到`text`类型中的优势在于它能够为结构良好性来检查输入值， 并且还支持函数对其进行类型安全性检查，可参阅第 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`可以是`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数据格式都能支持。

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

## 8.13.2. 编码处理

在对客户端和服务器端进行多字符编码，以及在通过它们传递XML数据时需要格外注意。 当使用文本模式（正常模式）在服务器端和客户端之间传递查询和查询结果时， PostgreSQL在各自终端对所有传递的字符数据和字符编码进行相互转换，参阅第 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时，计算性能会很高。

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

## 8.13.3. 访问XML值

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

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

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

上一页 | 起始页 | 下一页
UUID 类型 | 上一级 | JSON 类型