============== XML 函数 ============== .. container:: sect1 :name: FUNCTIONS-XML .. container:: titlepage .. container:: .. container:: .. rubric:: XML 函数 :name: xml-函数 :class: title .. container:: toc 本节中描述的函数以及类函数的表达式都在类型\ ``xml``\ 的值上操作。类型\ ``xml``\ 的详细信息请参见\ `xml类型 `__\ 。用于在值和类型\ ``xml``\ 之间转换的类函数的表达式\ ``xmlparse``\ 和\ ``xmlserialize``\ 记录在这里,而不是在本节中。 .. container:: sect2 :name: FUNCTIONS-PRODUCING-XML .. container:: titlepage .. container:: .. container:: .. rubric:: 产生 XML 内容 :name: 产生-xml-内容 :class: title 有一组函数和类函数的表达式可以用来从 SQL 数据产生 XML 内容。它们特别适合于将查询结果格式化成 XML 文档以便于在客户端应用中处理。 .. container:: sect3 :name: id-1.5.8.19.5.3 .. container:: titlepage .. container:: .. container:: .. rubric:: ``xmlcomment`` :name: xmlcomment :class: title .. code:: synopsis xmlcomment(text) 函数\ ``xmlcomment``\ 创建了一个 XML 值,它包含一个使用指定文本作为内容的 XML 注释。该文本不包含“\ ``--``\ ”或者也不会以一个“\ ``-``\ ”结尾,这样结果的结构是一个合法的 XML 注释。如果参数为空,结果也为空。 例子: .. code:: screen SELECT xmlcomment('hello'); xmlcomment -------------- .. container:: sect3 :name: id-1.5.8.19.5.4 .. container:: titlepage .. container:: .. container:: .. rubric:: ``xmlconcat`` :name: xmlconcat :class: title .. code:: synopsis xmlconcat(xml[, ...]) 函数\ ``xmlconcat``\ 将由单个 XML 值组成的列表串接成一个单独的值,这个值包含一个 XML 内容片断。空值会被忽略,只有当没有参数为非空时结果才为空。 例子: .. code:: screen SELECT xmlconcat('', 'foo'); xmlconcat ---------------------- foo 如果 XML 声明存在,它们会按照下面的方式被组合。如果所有的参数值都有相同的 XML 版本声明,该版本将被用在结果中,否则将不使用版本。如果所有参数值有独立声明值“yes”,那么该值将被用在结果中。如果所有参数值都有一个独立声明值并且至少有一个为“no”,则“no”被用在结果中。否则结果中将没有独立声明。如果结果被决定要要求一个独立声明但是没有版本声明,将会使用一个版本 1.0 的版本声明,因为 XML 要求一个 XML 声明要包含一个版本声明。编码声明会被忽略并且在所有情况中都会被移除。 例子: .. code:: screen SELECT xmlconcat('', ''); xmlconcat ----------------------------------- .. container:: sect3 :name: id-1.5.8.19.5.5 .. container:: titlepage .. container:: .. container:: .. rubric:: ``xmlelement`` :name: xmlelement :class: title .. code:: synopsis xmlelement(name name [, xmlattributes(value [AS attname] [, ... ])] [, content, ...]) 表达式\ ``xmlelement``\ 使用给定名称、属性和内容产生一个 XML 元素。 例子: .. code:: screen SELECT xmlelement(name foo); xmlelement ------------ SELECT xmlelement(name foo, xmlattributes('xyz' as bar)); xmlelement ------------------ SELECT xmlelement(name foo, xmlattributes(current_date as bar), 'cont', 'ent'); xmlelement ------------------------------------- content 不是合法 XML 名字的元素名和属性名将被逃逸,逃逸的方法是将违反的字符用序列\ ``_xHHHH``\ \_替换,其中\ ``HHHH``\ 是被替换字符的 Unicode 代码点的十六进制表示。例如: .. code:: screen SELECT xmlelement(name "foo$bar", xmlattributes('xyz' as "a&b")); xmlelement ---------------------------------- 如果属性值是一个列引用,则不需要指定一个显式的属性名,在这种情况下列的名字将被默认用于属性的名字。在其他情况下,属性必须被给定一个显式名称。因此这个例子是合法的: .. code:: screen CREATE TABLE test (a xml, b xml); SELECT xmlelement(name test, xmlattributes(a, b)) FROM test; 但是下面这些不合法: .. code:: screen SELECT xmlelement(name test, xmlattributes('constant'), a, b) FROM test; SELECT xmlelement(name test, xmlattributes(func(a, b))) FROM test; 如果指定了元素内容,它们将被根据其数据类型格式化。如果内容本身也是类型\ ``xml``\ ,就可以构建复杂的 XML 文档。例如: .. code:: screen SELECT xmlelement(name foo, xmlattributes('xyz' as bar), xmlelement(name abc), xmlcomment('test'), xmlelement(name xyz)); xmlelement ---------------------------------------------- 其他类型的内容将被格式化为合法的 XML 字符数据。这意味着字符 <, >, 和 & 将被转换为实体。二进制数据(数据类型\ ``bytea``\ )将被表示成 base64 或十六进制编码,具体取决于配置参数xmlbinary的设置。 .. container:: sect3 :name: id-1.5.8.19.5.6 .. container:: titlepage .. container:: .. container:: .. rubric:: ``xmlforest`` :name: xmlforest :class: title .. code:: synopsis xmlforest(content [AS name] [, ...]) 表达式\ ``xmlforest``\ 使用给定名称和内容产生一个元素的 XML 森林(序列)。 例子: .. code:: screen SELECT xmlforest('abc' AS foo, 123 AS bar); xmlforest ------------------------------ abc123 SELECT xmlforest(table_name, column_name) FROM information_schema.columns WHERE table_schema = 'pg_catalog'; xmlforest ------------------------------------------------------------------------------------------- pg_authidrolname pg_authidrolsuper ... 如我们在第二个例子中所见,如果内容值是一个列引用,元素名称可以被忽略,这种情况下默认使用列名。否则,必须指定一个名字。 如上文\ ``xmlelement``\ 所示,非法 XML 名字的元素名会被逃逸。相似地,内容数据也会被逃逸来产生合法的 XML 内容,除非它已经是一个\ ``xml``\ 类型。 注意如果 XML 森林由多于一个元素组成,那么它不是合法的 XML 文档,因此在\ ``xmlelement``\ 中包装\ ``xmlforest``\ 表达式会有用处。 .. container:: sect3 :name: id-1.5.8.19.5.7 .. container:: titlepage .. container:: .. container:: .. rubric:: ``xmlpi`` :name: xmlpi :class: title .. code:: synopsis xmlpi(name target [, content]) 表达式\ ``xmlpi``\ 创建一个 XML 处理指令。如果存在内容,内容不能包含字符序列\ ``?>``\ 。 例子: .. code:: screen SELECT xmlpi(name php, 'echo "hello world";'); xmlpi ----------------------------- .. container:: sect3 :name: id-1.5.8.19.5.8 .. container:: titlepage .. container:: .. container:: .. rubric:: ``xmlroot`` :name: xmlroot :class: title .. code:: synopsis xmlroot(xml, version text | no value [, standalone yes|no|no value]) 表达式\ ``xmlroot``\ 修改一个 XML 值的根结点的属性。如果指定了一个版本,它会替换根节点的版本声明中的值;如果指定了一个独立设置,它会替换根节点的独立声明中的值。 .. code:: screen SELECT xmlroot(xmlparse(document 'abc'), version '1.0', standalone yes); xmlroot ---------------------------------------- abc .. container:: sect3 :name: FUNCTIONS-XML-XMLAGG .. container:: titlepage .. container:: .. container:: .. rubric:: ``xmlagg`` :name: xmlagg :class: title .. code:: synopsis xmlagg(xml) 和这里描述的其他函数不同,函数\ ``xmlagg``\ 是一个聚集函数。它将聚集函数调用的输入值串接起来,非常像\ ``xmlconcat``\ 所做的事情,除了串接是跨行发生的而不是在单一行的多个表达式上发生。聚集表达式的更多信息请见\ `聚集函数 `__\ 。 例子: .. code:: screen CREATE TABLE test (y int, x xml); INSERT INTO test VALUES (1, 'abc'); INSERT INTO test VALUES (2, ''); SELECT xmlagg(x) FROM test; xmlagg ---------------------- abc 为了决定串接的顺序,可以为聚集调用增加一个\ ``ORDER BY``\ 子句,如\ `值表达式 `__\ 中所述。例如: .. code:: screen SELECT xmlagg(x ORDER BY y DESC) FROM test; xmlagg ---------------------- abc 我们推荐在以前的版本中使用下列非标准方法,并且它们在特定情况下仍然有用: .. code:: screen SELECT xmlagg(x) FROM (SELECT * FROM test ORDER BY y DESC) AS tab; xmlagg ---------------------- abc .. container:: sect2 :name: FUNCTIONS-XML-PREDICATES .. container:: titlepage .. container:: .. container:: .. rubric:: XML 谓词 :name: xml-谓词 :class: title 这一节描述的表达式检查\ ``xml``\ 值的属性。 .. container:: sect3 :name: id-1.5.8.19.6.3 .. container:: titlepage .. container:: .. container:: .. rubric:: ``IS DOCUMENT`` :name: is-document :class: title .. code:: synopsis xml IS DOCUMENT 如果参数 XML 值是一个正确的 XML 文档,则\ ``IS DOCUMENT``\ 返回真,如果不是则返回假(即它是一个内容片断),或者是参数为空时返回空。文档和内容片断之间的区别请见\ `xml类型 `__\ 。 .. container:: sect3 :name: id-1.5.8.19.6.4 .. container:: titlepage .. container:: .. container:: .. rubric:: ``IS NOT DOCUMENT`` :name: is-not-document :class: title .. code:: synopsis xml IS NOT DOCUMENT 如果参数中的XML值是一个正确的XML文档,那么表达式\ ``IS NOT DOCUMENT``\ 返回假,否则返回真(也就是说它是一个内容片段),如果参数为空则返回空。 .. container:: sect3 :name: XML-EXISTS .. container:: titlepage .. container:: .. container:: .. rubric:: ``XMLEXISTS`` :name: xmlexists :class: title .. code:: synopsis XMLEXISTS(text PASSING [BY { REF | VALUE }] xml [BY { REF | VALUE }]) 函数\ ``xmlexists``\ 评价一个XPath 1.0表达式(第一个参数),以传递的XML值作为其上下文项。 如果评价的结果产生一个空节点集,该函数返回false,如果产生任何其他值,则返回true。 如果任何参数为空,则函数返回null。 作为上下文项传递的非空值必须是一个XML文档,而不是内容片段或任何非XML值。 例子: .. code:: screen SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY VALUE 'TorontoOttawa'); xmlexists ------------ t (1 row) ``BY REF``\ 和\ ``BY VALUE``\ 子句在OushuDB中被接受,在SQL标准中,\ ``xmlexists``\ 函数评估XML查询语言中的表达式,但OushuDB只允许使用XPath 1.0表达。 .. container:: sect3 :name: XML-IS-WELL-FORMED .. container:: titlepage .. container:: .. container:: .. rubric:: ``xml_is_well_formed`` :name: xml_is_well_formed :class: title .. code:: synopsis xml_is_well_formed(text) xml_is_well_formed_document(text) xml_is_well_formed_content(text) 这些函数检查一个\ ``text``\ 串是不是一个良构的 XML,返回一个布尔结果。\ ``xml_is_well_formed_document``\ 检查一个良构的文档,而\ ``xml_is_well_formed_content``\ 检查良构的内容。如果\ ``xmloption``\ 配置参数被设置为\ ``DOCUMENT``\ ,\ ``xml_is_well_formed``\ 会做第一个函数的工作;如果配置参数被设置为\ ``CONTENT``\ ,\ ``xml_is_well_formed``\ 会做第二个函数的工作。这意味着\ ``xml_is_well_formed``\ 对于检查一个到类型\ ``xml``\ 的简单造型是否会成功非常有用,而其他两个函数对于检查\ ``XMLPARSE``\ 的对应变体是否会成功有用。 例子: .. code:: screen SET xmloption TO DOCUMENT; SELECT xml_is_well_formed('<>'); xml_is_well_formed -------------------- f (1 row) SELECT xml_is_well_formed(''); xml_is_well_formed -------------------- t (1 row) SET xmloption TO CONTENT; SELECT xml_is_well_formed('abc'); xml_is_well_formed -------------------- t (1 row) SELECT xml_is_well_formed_document('bar'); xml_is_well_formed_document ----------------------------- t (1 row) SELECT xml_is_well_formed_document('bar'); xml_is_well_formed_document ----------------------------- f (1 row) 最后一个例子显示了这些检查也包括名字空间是否正确地匹配。 .. container:: sect2 :name: FUNCTIONS-XML-PROCESSING .. container:: titlepage .. container:: .. container:: .. rubric:: 处理 XML :name: 处理-xml :class: title 要处理数据类型\ ``xml``\ 的值, OushuDB 提供了函数\ ``xpath``\ 和\ ``xpath_exists``\ ,它们计算 XPath 1.0 表达式以及\ ``XMLTABLE``\ 表函数。 .. container:: sect3 :name: FUNCTIONS-XML-PROCESSING-XPATH .. container:: titlepage .. container:: .. container:: .. rubric:: ``xpath`` :name: xpath :class: title .. code:: synopsis xpath(xpath, xml [, nsarray]) 函数\ ``xpath``\ 在 XML 值\ ``xml``\ 上计算 XPath 1.0 表达式\ ``xpath`` (a ``text`` value)。它返回一个 XML 值的数组,该数组对应于该 XPath 表达式产生的结点集合。如果该 XPath 表达式返回一个标量值而不是一个结点集合,将会返回一个单一元素的数组。 第二个参数必须是一个良构的 XML 文档。特殊地,它必须有一个单一根结点元素。 该函数可选的第三个参数是一个名字空间映射的数组。这个数组应该是一个二维\ ``text``\ 数组,其第二轴长度等于2(即它应该是一个数组的数组,其中每一个都由刚好 2 个元素组成)。每个数组项的第一个元素是名字空间的名称(别名),第二个元素是名字空间的 URI。并不要求在这个数组中提供的别名和在 XML 文档本身中使用的那些名字空间相同(换句话说,在 XML 文档中和在\ ``xpath``\ 函数环境中,别名都是\ *本地的*\ )。 例子: .. code:: screen SELECT xpath('/my:a/text()', 'test', ARRAY[ARRAY['my', 'http://example.com']]); xpath -------- {test} (1 row) 要处理默认(匿名)命名空间,做这样的事情: .. code:: screen SELECT xpath('//mydefns:b/text()', 'test', ARRAY[ARRAY['mydefns', 'http://example.com']]); xpath -------- {test} (1 row) .. container:: sect3 :name: FUNCTIONS-XML-PROCESSING-XPATH-EXISTS .. container:: titlepage .. container:: .. container:: .. rubric:: ``xpath_exists`` :name: xpath_exists :class: title .. code:: synopsis xpath_exists(xpath, xml [, nsarray]) 函数\ ``xpath_exists``\ 是\ ``xpath``\ 函数的一种特殊形式。这个函数不是返回满足 XPath 1.0 表达式的单一 XML 值,它返回一个布尔值表示查询是否被满足(具体来说,它是否产生了空节点集以外的任何值)。这个函数等价于标准的\ ``XMLEXISTS``\ 谓词,不过它还提供了对一个名字空间映射参数的支持。 例子: .. code:: screen SELECT xpath_exists('/my:a/text()', 'test', ARRAY[ARRAY['my', 'http://example.com']]); xpath_exists -------------- t (1 row) .. container:: sect3 :name: FUNCTIONS-XML-PROCESSING-XMLTABLE .. container:: titlepage .. container:: .. container:: .. rubric:: ``xmltable`` :name: xmltable :class: title .. code:: synopsis xmltable( [XMLNAMESPACES(namespace uri AS namespace name[, ...]), ] row_expression PASSING [BY { REF | VALUE }] document_expression [BY { REF | VALUE }] COLUMNS name { type [PATH column_expression] [DEFAULT default_expression] [NOT NULL | NULL] | FOR ORDINALITY } [, ...] ) ``xmltable``\ 函数基于给定的XML值产生一个表、一个抽取行的XPath过滤器以及一个列定义集合。 可选的\ ``XMLNAMESPACES``\ 子句是一个逗号分隔的名字空间列表。它指定文档中使用的XML名字空间极其别名。当前不支持默认的名字空间说明。 所需的\ ``row_expression``\ 参数是一个XPath 1.0表达式,通过传递\ ``document_expression``\ 作为其上下文项,得到一组XML节点。这些节点就是\ ``xmltable``\ 转换为输出行的内容。如果\ ``document_expression``\ 为空,或者\ ``row_expression``\ 产生空节点集或节点集以外的任何值,则不会产生行。 ``document_expression``\ 提供了上下文。\ ``row_expression``\ 的项。它必须是一个格式良好的XML文档;不接受片段/森林。\ ``BY REF``\ 和\ ``BY VALUE``\ 子句 如上文所讨论的那样,被接受但被忽略了。在SQL标准中,\ ``xmltable``\ 函数 评估XML查询语言中的表达式。但OushuDB只允许使用XPath 1.0的 表达式 。 强制需要的\ ``COLUMNS``\ 子句指定输出表中的列列表。如果\ ``COLUMNS``\ 子句被省略,每一项描述一个列。格式请见上面的语法综述。列名和类型是必需的,路径、默认值以及为空性子句是可选的。 被标记为\ ``FOR ORDINALITY``\ 的列将按照从\ ``row_expression``\ 的结果节点集中检索到的节点的顺序,从1开始,填充行号。最多只能有一个列被标记为\ ``FOR ORDINALITY``\ 。 .. note:: .. rubric:: 注意 :name: 注意 :class: title XPath 1.0 并没有为节点集中的节点指定顺序,因此依赖特定结果顺序的代码将取决于实现 。 列的\ ``column_expression``\ 是一个XPath 1.0表达式,它对每一行都要进行求值,并以\ ``row_expression``\ 结果中的当前节点作为其上下文项,以找到列的值。 如果没有给出\ ``column_expression``\ ,那么列名被用作隐式路径。 如果一个列的XPath表达式返回一个非XML值(在XPath 1.0中仅限于string、boolean或double),而该列的OushuDB类型不是\ ``xml``\ ,那么该列将被设置为将值的字符串表示法分配给OushuDB类型。 (如果值是布尔值,如果输出列的类型类别是数字,那么它的字符串表示方式将被认为是\ ``1``\ 或\ ``0``\ ,否则\ ``true``\ 或 ``false``\ 。) 如果一个列的XPath表达式返回一个非空的XML节点集,并且该列的OushuDB类型是\ ``xml``\ ,那么如果该列是文档或内容形式的,那么该列将被精确地分配表达式结果。 `[8] <#ftn.id-1.5.8.19.7.5.14.2>`__ 分配给\ ``xml``\ 输出列的非XML结果会产生内容,一个带有结果字符串值的单个文本节点。分配给任何其他类型的列的XML结果不能有一个以上的节点,否则会产生错误。如果正好有一个节点,则该列将被设置为将该节点的字符串值(如XPath 1.0 ``string``\ 函数定义的那样)分配给OushuDB类型。 一个XML元素的字符串值是字符串值的协整,按文档的顺序。该元素中包含的所有文本节点及其子节点。字符串 元素的值是一个没有下级文本节点的元素的值是一个 空字符串(不是\ ``NULL``\ )。任何\ ``xsi:nil``\ 属性都会被忽略。请注意,两个非文本之间的\ ``text()``\ 节点只用空格,而两个非文本 元素,并且保留了\ ``text()``\ 上的前导白格。节点不被扁平化。XPath 1.0中的\ ``string``\ 函数可以参考XPath 1.0中的 定义其他XML节点类型和非XML值的字符串值的规则。 这里介绍的转换规则并不完全是SQL标准中的转换规则。 如果路径表达式为给定行返回一个空节点集(通常情况下,当它不匹配时),该列将被设置为\ ``NULL``\ ,除非指定了\ ``default_expression``\ ;然后使用评价该表达式产生的值。 列可能会被标记为\ ``NOT NULL``\ 。如果一个\ ``NOT NULL``\ 列的\ ``column_expression``\ 不匹配任何东西并且没有\ ``DEFAULT``\ 或者\ ``default_expression``\ 也计算为空,则会报告一个错误。 ``default_expression``\ ,而不是在调用\ ``xmltable``\ 时立即被评价,而是在每次需要列的默认值时,都会被评价。 如果表达式符合稳定或不可更改的条件,则可以跳过重复评价。 这意味着,你可以在\ ``default_expression``\ 中使用像\ ``nextval``\ 这样的不稳定函数。 例子: .. code:: screen CREATE TABLE xmldata AS SELECT xml $$ AU Australia JP Japan Shinzo Abe 145935 SG Singapore 697 $$ AS data; SELECT xmltable.* FROM xmldata, XMLTABLE('//ROWS/ROW' PASSING data COLUMNS id int PATH '@id', ordinality FOR ORDINALITY, "COUNTRY_NAME" text, country_id text PATH 'COUNTRY_ID', size_sq_km float PATH 'SIZE[@unit = "sq_km"]', size_other text PATH 'concat(SIZE[@unit!="sq_km"], " ", SIZE[@unit!="sq_km"]/@unit)', premier_name text PATH 'PREMIER_NAME' DEFAULT 'not specified') ; id | ordinality | COUNTRY_NAME | country_id | size_sq_km | size_other | premier_name ----+------------+--------------+------------+------------+--------------+--------------- 1 | 1 | Australia | AU | | | not specified 5 | 2 | Japan | JP | | 145935 sq_mi | Shinzo Abe 6 | 3 | Singapore | SG | 697 | | not specified 接下来的例子展示了多个text()节点的串接、列名用作XPath过滤器的用法以及对空格、XML注释和处理指令的处理: .. code:: screen CREATE TABLE xmlelements AS SELECT xml $$ Hello2a2 bbbxxxCC $$ AS data; SELECT xmltable.* FROM xmlelements, XMLTABLE('/root' PASSING data COLUMNS element text); element ---------------------- Hello2a2 bbbxxxCC 下面的例子展示了如何使用\ ``XMLNAMESPACES``\ 子句指定用在XML文档以及XPath表达式中的名字空间列表: .. code:: screen WITH xmldata(data) AS (VALUES (' '::xml) ) SELECT xmltable.* FROM XMLTABLE(XMLNAMESPACES('http://example.com/myns' AS x, 'http://example.com/b' AS "B"), '/x:example/x:item' PASSING (SELECT data FROM xmldata) COLUMNS foo int PATH '@foo', bar int PATH '@B:bar'); foo | bar -----+----- 1 | 2 3 | 4 4 | 5 (3 rows) .. container:: sect2 :name: FUNCTIONS-XML-MAPPING .. container:: titlepage .. container:: .. container:: .. rubric:: 将表映射到 XML :name: 将表映射到-xml :class: title 下面的函数将会把关系表的内容映射成 XML 值。它们可以被看成是 XML 导出功能: .. code:: synopsis table_to_xml(tbl regclass, nulls boolean, tableforest boolean, targetns text) query_to_xml(query text, nulls boolean, tableforest boolean, targetns text) cursor_to_xml(cursor refcursor, count int, nulls boolean, tableforest boolean, targetns text) 每一个函数的返回值都是\ ``xml``\ 。 ``table_to_xml``\ 映射由参数\ ``tbl``\ 传递的命名表的内容。\ ``regclass``\ 类型接受使用常见标记标识表的字符串,包括可选的模式限定和双引号。\ ``query_to_xml``\ 执行由参数\ ``query``\ 传递的查询并且映射结果集。\ ``cursor_to_xml``\ 从\ ``cursor``\ 指定的游标中取出指定数量的行。如果需要映射一个大型的表,我们推荐这种变体,因为每一个函数都是在内存中构建结果值的。 如果\ ``tableforest``\ 为假,则结果的 XML 文档看起来像这样: .. code:: screen data data ... ... 如果\ ``tableforest``\ 为真,结果是一个看起来像这样的 XML 内容片断: .. code:: screen data data ... ... 如果没有表名可用,在映射一个查询或一个游标时,在第一种格式中使用串\ ``table``\ ,在第二种格式中使用\ ``row``\ 。 这几种格式的选择由用户决定。第一种格式是一个正确的 XML 文档,它在很多应用中都很重要。如果结果值要被重组为一个文档,第二种格式在\ ``cursor_to_xml``\ 函数中更有用。前文讨论的产生 XML 内容的函数(特别是\ ``xmlelement``\ )可以被用来把结果修改成符合用户的要求。 数据值会被以前文的函数\ ``xmlelement``\ 中描述的相同方法映射。 参数\ ``nulls``\ 决定空值是否会被包含在输出中。如果为真,列中的空值被表示为: .. code:: screen 其中\ ``xsi``\ 是 XML 模式实例的 XML 名字空间前缀。一个合适的名字空间声明将被加入到结果值中。如果为假,包含空值的列将被从输出中忽略掉。 参数\ ``targetns``\ 指定想要的结果的 XML 名字空间。如果没有想要的特定名字空间,将会传递一个空串。 下面的函数返回 XML 模式文档,这些文档描述上述对应函数所执行的映射: .. code:: synopsis table_to_xmlschema(tbl regclass, nulls boolean, tableforest boolean, targetns text) query_to_xmlschema(query text, nulls boolean, tableforest boolean, targetns text) cursor_to_xmlschema(cursor refcursor, nulls boolean, tableforest boolean, targetns text) 最重要的是相同的参数被传递来获得匹配的 XML 数据映射和 XML 模式文档。 下面的函数产生 XML 数据映射和对应的 XML 模式,并把产生的结果链接在一起放在一个文档(或森林)中。在要求自包含和自描述的结果是它们非常有用: .. code:: synopsis table_to_xml_and_xmlschema(tbl regclass, nulls boolean, tableforest boolean, targetns text) query_to_xml_and_xmlschema(query text, nulls boolean, tableforest boolean, targetns text) 另外,下面的函数可用于产生相似的整个模式或整个当前数据库的映射: .. code:: synopsis schema_to_xml(schema name, nulls boolean, tableforest boolean, targetns text) schema_to_xmlschema(schema name, nulls boolean, tableforest boolean, targetns text) schema_to_xml_and_xmlschema(schema name, nulls boolean, tableforest boolean, targetns text) database_to_xml(nulls boolean, tableforest boolean, targetns text) database_to_xmlschema(nulls boolean, tableforest boolean, targetns text) database_to_xml_and_xmlschema(nulls boolean, tableforest boolean, targetns text) 注意这些函数可能产生很多数据,它们都需要在内存中被构建。在请求大型模式或数据库的内容映射时,可以考虑分别映射每一个表,甚至通过一个游标来映射。 一个模式内容映射的结果看起来像这样: .. code:: screen table1-mapping table2-mapping ... 其中一个表映射的格式取决于上文解释的\ ``tableforest``\ 参数。 一个数据库内容映射的结果看起来像这样: .. code:: screen ... ... ... 其中的模式映射如上所述。 作为一个使用这些函数产生的输出的例子,下图展示了一个 XSLT 样式表,它将\ ``table_to_xml_and_xmlschema``\ 的输出转换为一个包含表数据的扁平转印的 HTML 文档。以一种相似的方式,这些函数的结果可以被转换成其他基于 XML 的格式。 .. container:: figure :name: XSLT-XML-HTML **转换 SQL/XML 输出到 HTML 的 XSLT 样式表** .. container:: figure-contents .. code:: programlisting <xsl:value-of select="name(current())"/>
.. container:: footnotes -------------- .. container:: footnote :name: ftn.id-1.5.8.19.7.5.14.2 `[8] <#id-1.5.8.19.7.5.14.2>`__ 在顶层包含一个以上的元素节点的结果,或者在元素之外的非空格文本,就是内容形式的一个例子。一个XPath结果可以是这两种形式的,例如,如果它返回的是一个从包含它的元素中选择的属性节点。这样的结果将被放到内容形式中,每个不允许的节点都会被替换为它的字符串值,就像XPath 1.0\ ``string`` 函数定义的那样。