# D.3.XML限制和与SQL/XML的一致性

D.3.1.查询仅限于XPath 1.0D.3.2.实施的附带限制

SQL:2006对ISO/IEC 9075-14(SQL/XML)中与XML相关的规范进行了重大修订。PostgreSQL对XML数据类型和相关函数的实现在很大程度上遵循了2003年的早期版本,并借鉴了后来的版本。特别地:

  • 其中,当前标准提供了一系列XML数据类型,以保存非类型化或XML模式类型变体中的“文档”或“内容”,以及XML(序列)为了保存任意的XML内容,PostgreSQL提供了xml类型,可以保存“文档”或“内容”。没有与标准的“序列”类型对应的类型。

  • PostgreSQL提供了SQL:2006中引入的两个函数,但其变体使用的是XPath 1.0语言,而不是标准中为其指定的XML查询。

    本节介绍了您可能会遇到的一些差异。

# D.3.1.查询仅限于XPath 1.0

特定于PostgreSQL的函数xpath()xpath_exists()使用XPath语言查询XML文档。PostgreSQL还提供了标准函数的仅限XPath的变体XMLEXISTSXMLTABLE,正式使用XQuery语言。对于所有这些函数,PostgreSQL依赖于libxml2库,它只提供XPath 1.0.

XQuery语言和XPath 2.0及更高版本之间有着紧密的联系:任何语法有效且在这两个版本中成功执行的表达式都会产生相同的结果(对于包含数字字符引用或预定义实体引用的表达式,有一个小的例外,XQuery将其替换为相应的字符,而XPath则不使用它们)。但这些语言与XPath 1.0之间没有这种联系;这是一种早期的语言,在许多方面有所不同。

有两类限制需要记住:对于SQL标准中指定的函数,从XQuery到XPath的限制;对于标准函数和PostgreSQL特定函数,从XPath到1.0版本的限制。

# D.3.1.1.XQuery对XPath的限制

XQuery超越XPath的功能包括:

  • 除了所有可能的XPath值之外,XQuery表达式还可以构造并返回新的XML节点。XPath可以创建和返回原子类型(数字、字符串等)的值,但只能返回作为表达式输入提供的文档中已经存在的XML节点。

  • XQuery具有用于迭代、排序和分组的控制结构。

  • XQuery允许声明和使用本地函数。

    最近的XPath版本开始提供与这些功能重叠的功能(例如函数样式)每人分类、匿名函数和解析xml但在XPath 3.0之前,这些功能是不可用的。

# D.3.1.2.将XPath限制为1.0

对于熟悉XQuery和XPath 2.0或更高版本的开发人员,XPath 1.0提供了一些需要解决的差异:

  • XQuery/XPath表达式的基本类型序列XPath 1.0中不存在,它可以包含XML节点和/或原子值。1.0表达式只能生成一个节点集(包含零个或多个XML节点)或一个原子值。

  • 与XQuery/XPath序列不同,XQuery/XPath序列可以以任何所需的顺序包含任何所需的项,XPath 1.0节点集没有保证的顺序,并且与任何集合一样,不允许同一项多次出现。

    # 笔记

    libxml2库似乎总是以输入文档中相同的相对顺序将节点集及其成员返回给PostgreSQL。它的文档不支持这种行为,XPath 1.0表达式无法控制它。

  • 虽然XQuery/XPath提供了XML模式中定义的所有类型以及这些类型上的许多运算符和函数,但XPath 1.0只有节点集和三种原子类型布尔值, 双重的一串.

  • XPath 1.0没有条件运算符。XQuery/XPath表达式,例如如果是(帽子),那么hat/@size else“无帽子”没有与XPath 1.0等效的。

  • XPath 1.0没有字符串的排序比较运算符。二者都“猫”<“狗”“猫”>“狗”都是假的,因为每个都是两个的数值比较s、 相比之下,=!=将字符串作为字符串进行比较。

  • XPath 1.0模糊了价值比较一般比较正如XQuery/XPath定义的那样。二者都销售额/@hatsize=7sale/@customer=“alice”是否存在量化的比较,如果存在,则为真出售属性的给定值,但是销售/@应税=假()是与有效布尔值整个节点集的。如果没有,这才是真的出售有一个应纳税的一点也不。

  • 在XQuery/XPath数据模型中文档节点可以有文档形式(即,只有一个顶层元素,只有注释和处理指令在其之外)或内容形式(放松这些约束)。它在XPath 1.0中的等价物根节点,只能是文档形式。这也是xml作为上下文项传递给任何基于PostgreSQL XPath的函数的值必须是文档形式。

    这里强调的差异并不是全部。在XQuery和XPath的2.0及更高版本中,有一个XPath 1.0兼容模式,W3C列出了函数库更改 (opens new window)语言变化 (opens new window)在这种模式下应用提供了一个更完整(但仍然不是详尽)的差异说明。兼容性模式不能使以后的语言完全等同于XPath 1.0.

# D.3.1.3.SQL和XML数据类型和值之间的映射

在SQL:2006及更高版本中,标准SQL数据类型和XML模式类型之间的转换方向都被精确指定。然而,这些规则是使用XQuery/XPath的类型和语义表示的,并且没有直接应用于XPath 1.0的不同数据模型。

当PostgreSQL将SQL数据值映射到XML时(如xmlelement),或XML到SQL(如xmltable),除了特殊处理的少数情况外,PostgreSQL只是假设XML数据类型的XPath 1.0字符串形式将作为SQL数据类型的文本输入形式有效,反之亦然。该规则的优点是简单,同时对于许多数据类型,会产生类似于标准中指定的映射的结果。

如果需要考虑与其他系统的互操作性,对于某些数据类型,可能需要使用数据类型格式化功能(例如第9.8节)显式地生成标准映射。

# D.3.2.实施的附带限制

本节讨论的限制不是libxml2库固有的,但适用于PostgreSQL中的当前实现。

# D.3.2.1.只是按价值支持传递机制

SQL标准定义了两个传递机制在将XML参数从SQL传递给XML函数或接收结果时适用:参考,其中特定的XML值保留其节点标识,以及按价值,其中传递XML的内容,但不保留节点标识。可以在参数列表之前指定机制,作为所有参数的默认机制,也可以在任何参数之后指定机制,以覆盖默认机制。

为了说明区别,如果*十、*是一个XML值,SQL:2006环境中的这两个查询将分别生成true和false:

SELECT XMLQUERY('$a is $b' PASSING BY REF x AS a, x AS b NULL ON EMPTY);
SELECT XMLQUERY('$a is $b' PASSING BY VALUE x AS a, x AS b NULL ON EMPTY);

PostgreSQL将接受按价值参考在一个XMLEXISTSXMLTABLE构造,但它忽略了它们。这个xml数据类型持有字符串序列化的表示形式,因此没有需要保留的节点标识,传递总是有效的按价值.

# D.3.2.2.无法将命名参数传递给查询

基于XPath的函数支持传递一个参数作为XPath表达式的上下文项,但不支持传递附加值作为命名参数提供给表达式。

# D.3.2.3.没有XML(序列)类型

PostgreSQLxml数据类型只能在中保存一个值文件所容纳之物类型XQuery/XPath表达式上下文项必须是单个XML节点或原子值,但XPath 1.0进一步限制它仅为XML节点,并且没有允许的节点类型所容纳之物结果是一个结构良好的文件是PostgreSQL可以作为XPath上下文项提供的唯一XML值形式。