# 8.13.XML类型

8.13.1. 创建XML值

8.13.2. 编码处理

8.13.3. 访问XML值

这个xml数据类型可用于存储XML数据。它比将XML数据存储在文本字段用于检查输入值的格式是否正确,并且有支持函数对其执行类型安全操作;看见第9.15节.使用此数据类型需要安装时使用配置--使用libxml.

这个xml类型可以存储XML标准定义的格式良好的“文档”以及“内容”片段,这些片段通过引用更宽松的“文档节点” (opens new window)XQuery和XPath数据模型的。大致上,这意味着内容片段可以有多个顶级元素或字符节点。表情*xmlvalue*是文件吗可用于评估特定xml值是完整文档或仅是内容片段。

应用程序的限制和兼容性说明xml可以在中找到数据类型D.3节.

# 8.13.1.创建XML值

产生一种类型的价值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 AS type )

*类型*可以是性格, 性格多变文本(或其中一个的别名)。同样,根据SQL标准,这是在类型之间转换的唯一方法xml和字符类型,但PostgreSQL也允许您简单地转换值。

将字符串值转换为类型或从类型转换为字符串值时xml不经过XMLPARSEXMLSERIALIZE分别选择文件所容纳之物由“XML选项”决定会话配置参数,可使用标准命令设置:

SET XML OPTION { DOCUMENT | CONTENT };

或者更像PostgreSQL的语法

SET xmloption TO { DOCUMENT | CONTENT };

默认值是所容纳之物,因此所有形式的XML数据都是允许的。

# 8.13.2.编码处理

在处理客户机、服务器上的多个字符编码以及通过它们传递的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()特别地。

# 8.13.3.访问XML值

这个xml数据类型是不寻常的,因为它不提供任何比较运算符。这是因为对于XML数据没有定义良好且通用的比较算法。这样做的一个后果是,无法通过比较xml根据搜索值设置列。因此,XML值通常应附带一个单独的键字段,如ID。比较XML值的另一种解决方案是首先将其转换为字符串,但请注意,字符串比较与有用的XML比较方法几乎没有关系。

因为没有用于xml数据类型,不可能直接在这种类型的列上创建索引。如果需要快速搜索XML数据,可能的解决方法包括将表达式强制转换为字符串类型并对其进行索引,或对XPath表达式进行索引。当然,实际的查询必须调整为按索引表达式进行搜索。

PostgreSQL中的文本搜索功能还可用于加速XML数据的完整文档搜索。然而,必要的预处理支持在PostgreSQL发行版中尚不可用。