XML函数

本节中描述的函数以及类函数的表达式都在类型xml的值上操作。用于在值和类型xml之间转换的类函数的表达式xmlparsexmlserialize记录在这里,而不是在本节中。

使用大部分这些函数要求本数据库使用了configure --with-libxml进行编译。

产生XML内容

有一组函数和类函数的表达式可以用来从SQL数据产生XML内容。它们特别适合于将查询结果格式化成XML文档以便于在客户端应用中处理。

xmlcomment

    xmlcomment ( text ) → xml

函数xmlcomment创建了一个XML值,它包含一个使用指定文本作为内容的XML注释。 该文本不包含“--”或者也不会以一个“-”结尾,否则该结果的结构不是一个合法的XML注释。如果参数为空,结果也为空。

示例:

    SELECT xmlcomment('hello');

      xmlcomment
    --------------
     <!--hello-->

xmlconcat

    xmlconcat ( xml [, ...] ) → xml

函数xmlconcat将由单个 XML 值组成的列表串接成一个单独的值,这个值包含一个XML内容片段。空值会被忽略,只有当没有参数为非空时结果才为空。

示例:

    SELECT xmlconcat('<abc/>', '<bar>foo</bar>');

          xmlconcat
    ----------------------
     <abc/><bar>foo</bar>

如果XML声明存在,它们会按照下面的方式被组合。如果所有的参数值都有相同的XML版本声明,该版本将被用在结果中,否则将不使用版本。如果所有参数值有独立声明值“yes”,那么该值将被用在结果中。如果所有参数值都有一个独立声明值并且至少有一个为“no”,则“no”被用在结果中。否则结果中将没有独立声明。如果结果被决定要求一个独立声明但是没有版本声明,将会使用一个版本 1.0 的版本声明,因为XML要求一个XML声明要包含一个版本声明。编码声明会被忽略并且在所有情况中都会被移除。

示例:

    SELECT xmlconcat('<?xml version="1.1"?><foo/>', '<?xml version="1.1" standalone="no"?><bar/>');

                 xmlconcat
    -----------------------------------
     <?xml version="1.1"?><foo/><bar/>

xmlelement

    xmlelement ( NAME name [, XMLATTRIBUTES ( attvalue [ AS attname ] [, ...] ) ] [, content [, ...]] ) → xml

表达式xmlelement使用给定名称、属性和内容产生一个XML元素。 语法中显示的nameattname项是简单的标识符,而不是值。 attvaluecontent项是表达式,它们可以生成任何本数据库数据类型。 XMLATTRIBUTES的参数生成XML元素的属性;将content值连接起来形成其内容。

示例:

    SELECT xmlelement(name foo);

     xmlelement
    ------------
     <foo/>

    SELECT xmlelement(name foo, xmlattributes('xyz' as bar));

        xmlelement
    ------------------
     <foo bar="xyz"/>

    SELECT xmlelement(name foo, xmlattributes(current_date as bar), 'cont', 'ent');

                 xmlelement
    -------------------------------------
     <foo bar="2007-01-26">content</foo>

不是合法XML名字的元素名和属性名将被逃逸,逃逸的方法是将违反的字符用序列_x``HHHH``_替换,其中HHHH是被替换字符的Unicode代码点的十六进制表示。例如:

    SELECT xmlelement(name "foo$bar", xmlattributes('xyz' as "a&b"));

                xmlelement
    ----------------------------------
     <foo_x0024_bar a_x0026_b="xyz"/>

如果属性值是一个列引用,则不需要指定一个显式的属性名,在这种情况下列的名字将被默认用于属性的名字。在其他情况下,属性必须被给定一个显式名称。因此该示例是合法的:

    CREATE TABLE test (a xml, b xml);
    SELECT xmlelement(name test, xmlattributes(a, b)) FROM test;

但是下面这些不合法:

    SELECT xmlelement(name test, xmlattributes('constant'), a, b) FROM test;
    SELECT xmlelement(name test, xmlattributes(func(a, b))) FROM test;

如果指定了元素内容,它们将被根据其数据类型格式化。如果内容本身也是类型xml,就可以构建复杂的XML文档。例如:

    SELECT xmlelement(name foo, xmlattributes('xyz' as bar),
                                xmlelement(name abc),
                                xmlcomment('test'),
                                xmlelement(name xyz));

                      xmlelement
    ----------------------------------------------
     <foo bar="xyz"><abc/><!--test--><xyz/></foo>

其他类型的内容将被格式化为合法的XML字符数据。这意味着字符 <, >, 和&将被转换为实体。二进制数据(数据类型bytea)将被表示成base64或十六进制编码,具体取决于配置参数xmlbinary的设置。

xmlforest

    xmlforest ( content [ AS name ] [, ...] ) → xml

表达式xmlforest使用给定名称和内容产生一个元素的XML森林(序列)。 对于xmlelement,每个name都必须是一个简单的标识符,而content表达式可以有任何数据类型。

示例:

    SELECT xmlforest('abc' AS foo, 123 AS bar);

              xmlforest
    ------------------------------
     <foo>abc</foo><bar>123</bar>


    SELECT xmlforest(table_name, column_name)
    FROM information_schema.columns
    WHERE table_schema = 'pg_catalog';

                                    xmlforest
    ------------------------------------​-----------------------------------
     <table_name>pg_authid</table_name>​<column_name>rolname</column_name>
     <table_name>pg_authid</table_name>​<column_name>rolsuper</column_name>
     ...

如我们在第二个示例中所见,如果内容值是一个列引用,元素名称可以被忽略,这种情况下默认使用列名。否则,必须指定一个名字。

如上文xmlelement所示,非法XML名字的元素名会被逃逸。相似地,内容数据也会被逃逸来产生合法的XML内容,除非它已经是一个xml类型。

说明

如果XML森林由多于一个元素组成,那么它不是合法的XML文档,因此在xmlelement中包装xmlforest表达式会有用处。

xmlpi

    xmlpi ( NAME name [, content ] ) → xml

表达式xmlpi创建一个XML处理指令。 对于xmlelementname必须是一个简单的标识符,而content表达式可以有任何数据类型。如果存在,content不能包含字符序列?>

示例:

    SELECT xmlpi(name php, 'echo "hello world";');

                xmlpi
    -----------------------------
     <?php echo "hello world";?>

xmlroot

    xmlroot ( xml, VERSION {text|NO VALUE} [, STANDALONE {YES|NO|NO VALUE} ] ) → xml

表达式xmlroot修改一个XML值的根节点的属性。如果指定了一个版本,它会替换根节点的版本声明中的值;如果指定了一个独立设置,它会替换根节点的独立声明中的值。

    SELECT xmlroot(xmlparse(document '<?xml version="1.1"?><content>abc</content>'),
                   version '1.0', standalone yes);

                    xmlroot
    ----------------------------------------
     <?xml version="1.0" standalone="yes"?>
     <content>abc</content>

xmlagg

    xmlagg ( xml ) → xml

和这里描述的其他函数不同,函数xmlagg是一个聚集函数。它将聚集函数调用的输入值串接起来,非常像xmlconcat所做的事情,除了串接是跨行发生的而不是在单一行的多个表达式上发生。

示例:

    CREATE TABLE test (y int, x xml);
    INSERT INTO test VALUES (1, '<foo>abc</foo>');
    INSERT INTO test VALUES (2, '<bar/>');
    SELECT xmlagg(x) FROM test;
            xmlagg
    ----------------------
     <foo>abc</foo><bar/>

为了决定串接的顺序,可以为聚集调用增加一个ORDER BY子句。例如:

    SELECT xmlagg(x ORDER BY y DESC) FROM test;
            xmlagg
    ----------------------
     <bar/><foo>abc</foo>

推荐在以前的版本中使用下列非标准方法,并且它们在特定情况下仍然有用:

    SELECT xmlagg(x) FROM (SELECT * FROM test ORDER BY y DESC) AS tab;
            xmlagg
    ----------------------
     <bar/><foo>abc</foo>

XML谓词

这一节描述的表达式检查xml值的属性。

IS DOCUMENT

    xml IS DOCUMENT → boolean

如果参数XML值是一个正确的XML文档,则IS DOCUMENT返回真,如果不是则返回假(即它是一个内容片段),或者是参数为空时返回空。

IS NOT DOCUMENT

    xml IS NOT DOCUMENT → boolean

如果参数中的XML值是一个正确的XML文档,那么表达式IS NOT DOCUMENT返回假,否则返回真(也就是说它是一个内容片段),如果参数为空则返回空。

XMLEXISTS

    XMLEXISTS ( text PASSING [BY {REF|VALUE}] xml [BY {REF|VALUE}] ) → boolean

函数xmlexists评价一个XPath 1.0表达式(第一个参数),以传递的XML值作为其上下文项。 如果评价的结果产生一个空节点集,该函数返回false,如果产生任何其他值,则返回true。 如果任何参数为空,则函数返回null。 作为上下文项传递的非空值必须是一个XML文档,而不是内容片段或任何非XML值。

示例:

    SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY VALUE '<towns><town>Toronto</town><town>Ottawa</town></towns>');

     xmlexists
    ------------
     t
    (1 row)

在SQL标准中,xmlexists函数评估XML查询语言中的表达式,但本数据库只允许使用XPath 1.0表达式。

xml_is_well_formed

    xml_is_well_formed ( text ) → boolean
    xml_is_well_formed_document ( text ) → boolean
    xml_is_well_formed_content ( text ) → boolean

这些函数检查一个text串是不是一个良构的XML,返回一个布尔结果。xml_is_well_formed_document检查一个良构的文档,而xml_is_well_formed_content检查良构的内容。如果xmloption配置参数被设置为DOCUMENTxml_is_well_formed会做第一个函数的工作;如果配置参数被设置为CONTENTxml_is_well_formed会做第二个函数的工作。这意味着xml_is_well_formed对于检查一个到类型xml的简单造型是否会成功非常有用,而其他两个函数对于检查XMLPARSE的对应变体是否会成功有用。

示例:

    SET xmloption TO DOCUMENT;
    SELECT xml_is_well_formed('<>');
     xml_is_well_formed
    --------------------
     f
    (1 row)

    SELECT xml_is_well_formed('<abc/>');
     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('<pg:foo xmlns:pg="http://postgresql.org/stuff">bar</pg:foo>');
     xml_is_well_formed_document
    -----------------------------
     t
    (1 row)

    SELECT xml_is_well_formed_document('<pg:foo xmlns:pg="http://postgresql.org/stuff">bar</my:foo>');
     xml_is_well_formed_document
    -----------------------------
     f
    (1 row)

最后一个示例显示了这些检查也包括名字空间是否正确地匹配。

处理 XML

要处理数据类型xml的值, PostgreSQL提供了函数xpathxpath_exists,它们计算XPath 1.0表达式以及XMLTABLE表函数。

xpath

    xpath ( xpath text, xml xml [, nsarray text[] ] ) → xml[]

函数xpath根据 XML 值xml计算 XPath 1.0 表达式xpath (以文本形式给出)。 它返回一个XML值的数组,该数组对应于该XPath表达式产生的节点集合。 如果该XPath表达式返回一个标量值而不是一个节点集合,将会返回一个单一元素的数组。

第二个参数必须是一个良构的XML文档。特殊地,它必须有一个单一根节点元素。

该函数可选的第三个参数是一个名字空间映射的数组。这个数组应该是一个二维text数组,其第二轴长度等于 2(即它应该是一个数组的数组,其中每一个都由刚好 2 个元素组成)。每个数组项的第一个元素是名字空间的名称(别名),第二个元素是名字空间的 URI。并不要求在这个数组中提供的别名和在XML文档本身中使用的那些名字空间相同(换句话说,在XML文档中和在xpath函数环境中,别名都是本地的)。

示例:

    SELECT xpath('/my:a/text()', '<my:a xmlns:my="http://example.com">test</my:a>',
                 ARRAY[ARRAY['my', 'http://example.com']]);

     xpath
    --------
     {test}
    (1 row)

要处理默认(匿名)命名空间,做这样的事情:

    SELECT xpath('//mydefns:b/text()', '<a xmlns="http://example.com"><b>test</b></a>',
                 ARRAY[ARRAY['mydefns', 'http://example.com']]);

     xpath
    --------
     {test}
    (1 row)

xpath_exists

    xpath_exists ( xpath text, xml xml [, nsarray text[] ] ) → boolean

函数xpath_existsxpath函数的一种特殊形式。这个函数不是返回满足XPath 1.0表达式的单一XML值,它返回一个布尔值表示查询是否被满足(具体来说,它是否产生了空节点集以外的任何值)。这个函数等价于标准的XMLEXISTS谓词,不过它还提供了对一个名字空间映射参数的支持。

示例:

    SELECT xpath_exists('/my:a/text()', '<my:a xmlns:my="http://example.com">test</my:a>',
                         ARRAY[ARRAY['my', 'http://example.com']]);

     xpath_exists
    --------------
     t
    (1 row)

xmltable

    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 }
                [, ...]
    ) → setof record

xmltable表达式基于给定的XML值产生一个表、一个抽取行的XPath过滤器以及一个列定义集合。 虽然它在语法上类似于函数,但它只能作为一个表出现在查询的FROM子句中。

可选的XMLNAMESPACES子句是一个逗号分隔的名字空间定义列表。 其中每个namespace_uri是一个text表达式,每个namespace_name是一个简单的标识符。 它指定文档中使用的XML名字空间及其别名。当前不支持默认的名字空间说明。

所需的row_expression参数是一个求值的XPath 1.0表达式(以text形式给出),通过传递XML值document_expression作为其上下文项,得到一组XML节点。 这些节点就是xmltable转换为输出行的内容。如果document_expression为空,或者row_expression产生空节点集或节点集以外的任何值,则不会产生行。

document_expression提供了上下文。row_expression的项。 它必须是一个格式良好的XML文档;不接受片段/森林。BY REFBY VALUE子句如上文所讨论的那样,被接受但被忽略了。

在SQL标准中,xmltable函数评估XML查询语言中的表达式。 但本数据库只允许使用XPath 1.0的表达式。

需要的COLUMNS子句指定将在输出表中生成的列。有关格式,请参阅上面的语法摘要。 每个列都需要一个名称,作为一个数据类型(除非指定了 FOR ORDINALITY,在这种情况下类型 integer是隐式的)。 路径、默认值以及为空型子句是可选的。

被标记为FOR ORDINALITY的列将按照从row_expression的结果节点集中检索到的节点的顺序,从1开始,填充行号。最多只能有一个列被标记为FOR ORDINALITY

重要

XPath 1.0并没有为节点集中的节点指定顺序,因此依赖特定结果顺序的代码将取决于实现。

列的column_expression是一个XPath 1.0表达式,它对每一行都要进行求值,并以row_expression结果中的当前节点作为其上下文项,以找到列的值。 如果没有给出column_expression,那么列名被用作隐式路径。

如果一个列的XPath表达式返回一个非XML值(在XPath 1.0中仅限于string、boolean或double),而该列的PostgreSQL类型不是xml,那么该列将被设置为将值的字符串表示法分配给PostgreSQL类型。 (如果值是布尔值,如果输出列的类型类别是数字,那么它的字符串表示方式将被认为是10,否则truefalse)。

如果一个列的XPath表达式返回一个非空的XML节点集,并且该列的PostgreSQL类型是xml,那么如果该列是文档或内容形式的,那么该列将被精确地分配表达式结果。 [7]

分配给xml输出列的非XML结果会产生内容,一个带有结果字符串值的单个文本节点。分配给任何其他类型的列的XML结果不能有一个以上的节点,否则会产生错误。如果正好有一个节点,则该列将被设置为将该节点的字符串值(如XPath 1.0 string函数定义的那样)分配给PostgreSQL类型。

一个XML元素的字符串值是字符串值的协整,按文档的顺序。该元素中包含的所有文本节点及其子节点。字符串元素的值是一个没有下级文本节点的元素的值是一个空字符串(不是NULL)。任何xsi:nil属性都会被忽略。请注意,两个非文本之间的text()节点只用空格,而两个非文本元素,并且保留了text()上的前导白格。节点不被扁平化。XPath 1.0中的string函数可以参考XPath 1.0中的定义其他XML节点类型和非XML值的字符串值的规则。

如果路径表达式为给定行返回一个空节点集(通常情况下,当它不匹配时),该列将被设置为NULL,除非指定了default_expression;然后使用评价该表达式产生的值。

default_expression,而不是在调用xmltable时立即被评价,而是在每次需要列的默认值时,都会被评价。 如果表达式符合稳定或不可更改的条件,则可以跳过重复评价。 这意味着,你可以在default_expression中使用像nextval这样的不稳定函数。

列可能会被标记为NOT NULL。如果一个NOT NULL列的column_expression不匹配任何东西并且没有DEFAULT或者default_expression也计算为空,则会报告一个错误。

示例:

    CREATE TABLE xmldata AS SELECT
    xml $$
    <ROWS>
      <ROW id="1">
        <COUNTRY_ID>AU</COUNTRY_ID>
        <COUNTRY_NAME>America</COUNTRY_NAME>
      </ROW>
      <ROW id="5">
        <COUNTRY_ID>JP</COUNTRY_ID>
        <COUNTRY_NAME>Japan</COUNTRY_NAME>
        <PREMIER_NAME>Shinzo Abe</PREMIER_NAME>
        <SIZE unit="sq_mi">145935</SIZE>
      </ROW>
      <ROW id="6">
        <COUNTRY_ID>SG</COUNTRY_ID>
        <COUNTRY_NAME>Singapore</COUNTRY_NAME>
        <SIZE unit="sq_km">697</SIZE>
      </ROW>
    </ROWS>
    $$ 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 | America      | US         |            |              | not specified
      5 |          2 | Japan        | JP         |            | 145935 sq_mi | Shinzo Abe
      6 |          3 | Singapore    | SG         |        697 |              | not specified

接下来的示例展示了多个text()节点的串接、列名用作XPath过滤器的用法以及对空格、XML注释和处理指令的处理:

    CREATE TABLE xmlelements AS SELECT
    xml $$
      <root>
       <element>  Hello<!-- xyxxz -->2a2<?aaaaa?> <!--x-->  bbb<x>xxx</x>CC  </element>
      </root>
    $$ AS data;

    SELECT xmltable.*
      FROM xmlelements, XMLTABLE('/root' PASSING data COLUMNS element text);
             element
    -------------------------
       Hello2a2   bbbxxxCC

下面的示例展示了如何使用XMLNAMESPACES子句指定用在XML文档以及XPath表达式中的名字空间列表:

    WITH xmldata(data) AS (VALUES ('
    <example xmlns="http://example.com/myns" xmlns:B="http://example.com/b">
     <item foo="1" B:bar="2"/>
     <item foo="3" B:bar="4"/>
     <item foo="4" B:bar="5"/>
    </example>'::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)

将表映射到XML

下面的函数将会把关系表的内容映射成XML值。它们可以被看成是XML导出功能:

    table_to_xml ( table regclass, nulls boolean,
                   tableforest boolean, targetns text ) → xml
    query_to_xml ( query text, nulls boolean,
                   tableforest boolean, targetns text ) → xml
    cursor_to_xml ( cursor refcursor, count integer, nulls boolean,
                    tableforest boolean, targetns text ) → xml

table_to_xml映射由参数table传递的命名表的内容。regclass类型接受使用常见标记标识表的字符串,包括可选的模式限定和双引号。query_to_xml执行由参数query传递的查询并且映射结果集。cursor_to_xmlcursor指定的游标中取出指定数量的行。如果需要映射一个大型的表,我们推荐这种变体,因为每一个函数都是在内存中构建结果值的。

如果tableforest为假,则结果的XML文档看起来如下:

    <tablename>
      <row>
        <columnname1>data</columnname1>
        <columnname2>data</columnname2>
      </row>

      <row>
        ...
      </row>

      ...
    </tablename>

如果tableforest为真,结果是一个看起来像这样的XML内容片段:

    <tablename>
      <columnname1>data</columnname1>
      <columnname2>data</columnname2>
    </tablename>

    <tablename>
      ...
    </tablename>

    ...

如果没有表名可用,在映射一个查询或一个游标时,在第一种格式中使用串table,在第二种格式中使用row

这几种格式的选择由用户决定。第一种格式是一个正确的XML文档,它在很多应用中都很重要。如果结果值要被重组为一个文档,第二种格式在cursor_to_xml函数中更有用。前文讨论的产生XML内容的函数(特别是xmlelement)可以被用来把结果修改成符合用户的要求。

数据值会被以前文的函数xmlelement中描述的相同方法映射。

参数nulls决定空值是否会被包含在输出中。如果为真,列中的空值被表示为:

    <columnname xsi:nil="true"/>

其中xsi是XML模式实例的XML名字空间前缀。一个合适的名字空间声明将被加入到结果值中。如果为假,包含空值的列将被从输出中忽略掉。

参数targetns指定想要的结果的XML名字空间。如果没有想要的特定名字空间,将会传递一个空串。

下面的函数返回XML模式文档,这些文档描述上述对应函数所执行的映射:

    table_to_xmlschema ( table regclass, nulls boolean,
                         tableforest boolean, targetns text ) → xml
    query_to_xmlschema ( query text, nulls boolean,
                         tableforest boolean, targetns text ) → xml
    cursor_to_xmlschema ( cursor refcursor, nulls boolean,
                          tableforest boolean, targetns text ) → xml

最重要的是相同的参数被传递来获得匹配的XML数据映射和XML模式文档。

下面的函数产生XML数据映射和对应的XML模式,并把产生的结果链接在一起放在一个文档(或森林)中。在要求自包含和自描述的结果是它们非常有用:

    table_to_xml_and_xmlschema ( table regclass, nulls boolean,
                                 tableforest boolean, targetns text ) → xml
    query_to_xml_and_xmlschema ( query text, nulls boolean,
                                 tableforest boolean, targetns text ) → xml

另外,下面的函数可用于产生相似的整个模式或整个当前数据库的映射:

    schema_to_xml ( schema name, nulls boolean,
                    tableforest boolean, targetns text ) → xml
    schema_to_xmlschema ( schema name, nulls boolean,
                          tableforest boolean, targetns text ) → xml
    schema_to_xml_and_xmlschema ( schema name, nulls boolean,
                                  tableforest boolean, targetns text ) → xml

    database_to_xml ( nulls boolean,
                      tableforest boolean, targetns text ) → xml
    database_to_xmlschema ( nulls boolean,
                            tableforest boolean, targetns text ) → xml
    database_to_xml_and_xmlschema ( nulls boolean,
                                    tableforest boolean, targetns text ) → xml

这些函数会忽略当前用户不可读的表。数据库范围的函数还会忽略当前用户没有USAGE (查找)权限的模式。

请注意,这可能会产生大量数据,这些数据需要在内存中构建。 当请求大型模式或数据库的内容映射时,可能值得考虑单独映射表,甚至可能通过游标。

一个模式内容映射的结果看起来像这样:

    <schemaname>

    table1-mapping

    table2-mapping

    ...

    </schemaname>

其中一个表映射的格式取决于上文解释的tableforest参数。

一个数据库内容映射的结果看起来像这样:

    <dbname>

    <schema1name>
      ...
    </schema1name>

    <schema2name>
      ...
    </schema2name>

    ...

    </dbname>

其中的模式映射如上所述。

作为一个使用这些函数产生的输出的示例,转换SQL/XML输出到HTML的XSLT样式表展示了一个XSLT样式表,它将table_to_xml_and_xmlschema的输出转换为一个包含表数据的扁平转印的HTML文档。以一种相似的方式,这些函数的结果可以被转换成其他基于XML的格式。

转换SQL/XML输出到HTML的XSLT样式表**

    <?xml version="1.0"?>
    <xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        xmlns="http://www.w3.org/1999/xhtml"
    >

      <xsl:output method="xml"
          doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
          doctype-public="-//W3C/DTD XHTML 1.0 Strict//EN"
          indent="yes"/>

      <xsl:template match="/*">
        <xsl:variable name="schema" select="//xsd:schema"/>
        <xsl:variable name="tabletypename"
                      select="$schema/xsd:element[@name=name(current())]/@type"/>
        <xsl:variable name="rowtypename"
                      select="$schema/xsd:complexType[@name=$tabletypename]/xsd:sequence/xsd:element[@name='row']/@type"/>

        <html>
          <head>
            <title><xsl:value-of select="name(current())"/></title>
          </head>
          <body>
            <table>
              <tr>
                <xsl:for-each select="$schema/xsd:complexType[@name=$rowtypename]/xsd:sequence/xsd:element/@name">
                  <th><xsl:value-of select="."/></th>
                </xsl:for-each>
              </tr>

              <xsl:for-each select="row">
                <tr>
                  <xsl:for-each select="*">
                    <td><xsl:value-of select="."/></td>
                  </xsl:for-each>
                </tr>
              </xsl:for-each>
            </table>
          </body>
        </html>
      </xsl:template>

    </xsl:stylesheet>

在顶层包含一个以上的元素节点的结果,或者在元素之外的非空格文本,就是内容形式的一个示例。一个XPath结果可以是这两种形式的,例如,如果它返回的是一个从包含它的元素中选择的属性节点。这样的结果将被放到内容形式中,每个不允许的节点都会被替换为它的字符串值,就像XPath 1.0string 函数定义的那样。

XMLSERIALIZE

描述

该函数用于创建一个字符串或者包含value_expr内容的LOB

说明
  • 如果指定DOCUMENT,则value_expr必须是有效的XML文档。

  • 如果指定CONTENT,则value_expr不必是单根XML文档。但是,它必须是有效的XML内容。

  • 指定的数据类型可以是字符串类型(VARCHAR2或VARCHAR,但不能是NVARCHAR或NVARCHAR2)或CLOB。默认值为CLOB。

语法

XMLSERIALIZE({DOCUMENT|CEONTENT} value_expr [AS DATATYPE])

参数

参数

说明

{DOCUMENT|CEONTENT}

用于指定value_expr是内容还是文档。

value_expr

输入参数表达式。

[AS DATATYPE]

可选项,用于指定输入参数表达式转换为何种类型。

返回类型

返回字符串类型数据或者LOB类型数据。

示例

SELECT xmlserialize(content 'good' as char(10)) FROM DUAL;
 xmlserialize 
--------------
 good    

XMLROOT

描述

该函数允许通过在现有XML值和XML根信息中提供的版本和独立属性来创建新的XML值。

如果value_expr已经有prolog,则数据库将返回一个错误。如果输入为null,则函数返回null。

说明
  • 第一个值_expr指定要为其提供prolog信息的XML值。

  • VERSION子句中,value_expr必须解析为表示有效的XML版本的字符串。如果为VERSION指定“NO VALUE”,则版本默认为1.0。

  • 如果省略了可选的STANDALONE子句,或者使用NO VALUE指定它,则函数返回的值中没有独立属性。

语法

 XMLROOT(value_expr, VERSION {value_expr | NO VALUE} [, STANDALONE {YES | NO | NO VALUE}])

参数说明

参数

说明

value_expr

参数表达式。

VERSION {value_expr | NO VALUE}

指定版本,如果指定NO VALUE,则版本默认为1.0

STANDALONE {YES | NO | NO VALUE}

可选项,如果不指定或者指定为NO VALUE,则无独立属性。

返回类型

返回<?xml version = "version" \[ STANDALONE = "{yes | no}" \]?>格式的XML类型数据。

示例

 SELECT xmlroot(xml '<foo/>', version no value, standalone yes) FROM DUAL;
 xmlroot
 ----------------------------------------------
 <?xml version="1.0" standalone="yes"?><foo/>

XMLPI

描述

该函数用标识符和可选的value_expr的评估结果生成XML处理指令。处理指令通常用于向应用程序提供与XML文档的全部或部分相关联的信息。应用程序使用处理指令来确定如何最好地处理XML文档。

说明

XMLPI受以下限制:

  • 标识符必须是处理指令的有效目标。

  • 在任何情况下都不能为标识符指定xml组合。

  • 标识符不能包含连续字符?>

语法

 XMLPI([NAME] identifier[, value_expr])

参数说明

参数

说明

value_expr

参数表达式,必须解析为字符串。

返回类型

返回XML类型数据。

示例

SELECT xmlpi(name "xml-stylesheet", 'href="mystyle.css" type="text/css"');
 xmlpi
 -------------------------------------------------------
 <?xml-stylesheet href="mystyle.css" type="text/css"?>

XMLPARSE

描述

该函数根据value_expr的计算结果解析并生成一个XML实例。value_expr必须解析为字符串。如果value_expr解析为null,则函数返回null

语法

XMLPARSE({DOCUMENT|CONTENT}, value_expr[, WELLFORMED])

参数

参数

说明

DOCUMENT

可选项,选DOCUMENTvalue_expr必须解析为单个XML文档。

CONTENT

可选项,选CONTENTvalue_expr必须解析为有效的XML值。

value_expr

参数表达式。

WELLFORMED

可选项,当指定WELLFORMED时,因为指定这个变量是保证value_expr解析为格式正确的XML文档,因此此时数据库不会执行有效性检查以确保输入格式正确。

返回类型

返回XML实例。

示例

SELECT XMLPARSE(DOCUMENT '<!DOCTYPE foo [<!ENTITY c SYSTEM "/etc/no.such.file">]><foo>&c;</foo>');
                               xmlparse                                
-----------------------------------------------------------------------
 <!DOCTYPE foo [<!ENTITY c SYSTEM "/etc/no.such.file">]><foo>&c;</foo>

XMLFOREST

描述

该函数用于将其每个参数转换为XML,然后返回一个XML片段,该片段是这些转换后的参数的串联。

说明
  • 如果value_expr是标量表达式,则可以省略AS子句,而Oracle数据库使用列名作为元素名称。

  • 如果value_expr是对象类型或集合,则AS子句是必需的,并且Oracle使用指定的c_alias作为封闭标记。别名(_alias)最多可以包含4000个字符。

  • 如果value_expr为 null,则不会为该value_exper创建任何元素。

语法

XMLFOREST(value_expr [AS c_alias] [, value_expr [AS c_alias], ...])

参数说明

参数

说明

value_expr

参数表达式。

c_alias

可选项,别名,在value_expr是对象类型或集合时是必需的。

返回类型

返回XML类型的串联。

示例

 CREATE TABLE testxmlschema.test3
 AS SELECT true c1,
 true::testboolxmldomain c2,
 '2013-02-21'::date c3,
 '2013-02-21'::testdatexmldomain c4;
 SELECT xmlforest(c1, c2, c3, c4) FROM testxmlschema.test3;
 xmlforest
 ------------------------------------------------------------------
 <c1>true</c1><c2>true</c2><c3>2013-02-21</c3><c4>2013-02-21</c4>

XMLCONCAT

描述

XMLConcat将一系列XMLType实例作为输入,连接每行的一系列元素,并返回连接的系列。XMLConcat与XMLSequence相反。

null表达式将从结果中删除。如果所有的值表达式都为null,那么函数将返回null。

语法

 XMLCONCAT(XMLType_instance[, XMLType_instance, ...])

参数说明

参数

说明

XMLType_instance

用于指定XMLType的示例。

返回类型

返回连接的XMLType实例的系列。

示例

 SELECT xmlconcat('hello', 'you') FROM DUAL;
 xmlconcat
 -----------
 helloyou

EXTRACTVALUE

描述

该函数将XMLType实例和XPath表达式作为参数,并返回结果节点的标量值。结果必须是单个节点,并且必须是文本节点、属性或元素。如果结果是一个元素,那么该元素必须有一个单独的文本节点作为其子节点,函数返回的就是这个值。可以使用初始斜杠指定绝对XPath_string,也可以通过省略初始斜杠指定相对XPath_string。如果省略初始斜杠,则相对路径的上下文默认为根节点。

如果指定的XPath指向具有多个子节点的节点,或者指向的节点具有非文本节点子节点,则返回错误。可选的namespace_string必须解析为VARCHAR2值,该值指定前缀的默认映射或命名空间映射,在评估XPath表达式时使用该映射或命名空间。

语法

EXTRACTVALUE(XML Type_instance, XPath_string[, namespace_string])

参数

参数

说明

XMLType_instance

指定包含XML文档的XMLType实例。

XPath_string

VARCHAR2类型,指定路径。

namespace_string

可选项,VARCHAR2类型,namespace_string参数默认为根元素的命名空间。如果引用Xpath_string中的任何子元素,则必须指定namespace_string,并且必须在这两个参数中指定“谁”前缀。

返回类型

对于基于XML模式的文档,如果能够推断出返回值的类型,则会返回适当类型的标量值。否则,结果的类型为VARCHAR2。对于不基于XML模式的文档,返回类型始终为VARCHAR2。

示例

SELECT warehouse_name, 
   EXTRACTVALUE(e.warehouse_spec, '/Warehouse/Docks')
   "Docks"
   FROM warehouses e 
   WHERE warehouse_spec IS NOT NULL;

WAREHOUSE_NAME       Docks
-------------------- ------------
Southlake, Texas     2
San Francisco        1
New Jersey
Seattle, Washington  3

EXISTSNODE

描述

该函数用于确定使用指定路径遍历XML文档是否存在任何节点。它将包含XML文档的XMLType实例和指定路径的VARCHAR2类型XPath字符串作为参数。可选的namespace_string必须解析为VARCHAR2值,该值指定前缀的默认映射或命名空间映射,Oracle数据库在评估XPath表达式时使用该映射或命名空间。

  • 当遍历XPath之后,如果无节点则返回。

  • 如果有节点存在则返回0。

语法

EXISTSNODE(XMLType_instance, XPath_string[, namespace_string])

参数

参数

说明

XMLType_instance

指定包含XML文档的XMLType实例。

XPath_string

VARCHAR2类型,指定路径。

namespace_string

可选项,VARCHAR2类型,namespace_string参数默认为根元素的命名空间。如果引用Xpath_string中的任何子元素,则必须指定namespace_string,并且必须在这两个参数中指定“谁”前缀。

返回类型

返回BOOLEAN类型数据。

示例

SELECT warehouse_id, warehouse_name
  FROM warehouses
  WHERE EXISTSNODE(warehouse_spec, '/Warehouse/Docks') = 1
  ORDER BY warehouse_id;
 warehouse_id |   warehouse_name    
--------------+---------------------
            1 | Southlake, Texas
            2 | San Francisco
            4 | Seattle, Washington

DELETEXML

描述

该函数用于删除XML文档中满足XPath表达式的XML节点。它将XMLType类型的XML文档和指定路径的VARCHAR2类型的XPath字符串作为参数。

遍历XML文档之后,如果存在满足XPath表达式的XML节点,则将删除该节点后的XML文档返回;如果不存在这样的节点,则返回原XML文档。

语法

 DELETEXML(XMLType_instance, XPath_string)

参数说明

参数

说明

XMLType_instance

XMLType类型的XML文档。

XPath_string

VARCHAR2类型,指定路径。

返回类型

返回XMLType类型数据。

示例

CREATE TABLE SECTION AS
SELECT XMLTYPE('<section>
<question questionID="1">
<answer>US</answer>
<answer>XX</answer>
</question>
</section>') section_xml FROM dual;
-- delete all node
UPDATE SECTION s
SET s.section_xml = deleteXML(s.section_xml,
'//question[@questionID=1]/answer[2]');
SELECT s.section_xml FROM SECTION s;
		section_xml
---------------------------
<section> +
<question questionID="1">+
<answer>US</answer> +
						+
</question> +
</section> +

(1 row)

INSERTCHILDXML

描述

该函数用于在满足XPath表达式的XML节点的某一个子节点之后插入一个新的XML节点。它将XMLType类型的XML文档、指定路径的VARCHAR2类型的XPath字符串、VARCHAR2类型的子节点标签以及XMLType类型的待插入XML节点作为参数。

  • 遍历XML文档之后,如果存在满足XPath表达式的XML节点,且该节点存在一个子节点的标签与给定的子节点标签一致,则在最后一个满足子节点标签的子节点之后插入给定的XML节点。

  • 遍历XML文档之后,如果存在满足XPath表达式的XML节点,但该节点没有一个子节点的标签与给定子节点的标签一致,则在该节点的最后,插入给定的XML节点作为子节点。

语法

 INSERTCHILDXML(XMLType_instance, XPath_string, Node_string, XMLType_instance)

参数说明

参数

说明

XMLType_instance

XMLTyp 类型的XML文档。

XPath_string

VARCHAR2类型,指定路径。

Node_string

VARCHAR2类型,子节点的标签。

XMLType_instance

XMLType类型的XML节点。

返回类型

返回XMLType类型数据。

示例

CREATE TABLE SECTION AS
SELECT XMLTYPE('<section>
<question questionID="1">
<answer>US</answer>
<answer>XX</answer>
</question>
</section>') section_xml FROM dual;
-- delete all node
UPDATE SECTION s
SET s.section_xml = deleteXML(s.section_xml,
'//question[@questionID=1]/answer[2]');
SELECT s.section_xml FROM SECTION s;
		section_xml
---------------------------
<section> +
<question questionID="1">+
<answer>US</answer> +
						+
</question> +
</section> +

(1 row)