XMLELEMENT 标量函数

XMLELEMENT 函数返回的 XML 值是 XQuery 元素节点。

Read syntax diagramSkip visual syntax diagramXMLELEMENT(NAMEelement-name,xmlnamespaces-declaration,xmlattributes-function,element-content-expressionOPTION1EMPTY ON NULLNULL ON NULL2XMLBINARYUSINGBASE64XMLBINARYUSINGHEX3)
Notes:
  • 1 The OPTION clause can only be specified if at least one xmlattributes-function or element-content-expression is specified.
  • 2 NULL ON NULL or EMPTY ON NULL can only be specified if at least one element-content-expression is specified.
  • 3 The same clause must not be specified more than once.

该模式是 SYSIBM。 不能将函数名指定为限定名。

NAME 元素名称
指定 XML 元素的名称。 该名称是必须以 XML 限定名称或 QName (SQLSTATE 42634) 格式出现的 SQL 标识。 请参阅 W3C XML 名称空间规范 ,以获取有关有效名称的更多详细信息。 如果名称为限定名,那么必须在作用域中声明名称空间前缀 (SQLSTATE 42635)。
xmlnamespaces-声明
指定 XMLNAMESPACES 声明生成的 XML 名称空间声明。 声明的名称空间在 XMLELEMENT 函数作用域中。 不管是否出现在另一子查询中,这些名称空间都适用于 XMLELEMENT 函数内的任何嵌套 XML 函数。

如果未指定 xmlnamespaces-declaration,那么名称空间声明与已构造元素无关。

xmlattributes函数
指定元素的 XML 属性。 这些属性是 XMLATTRIBUTES 函数生成的。
元素内容表达式
生成的 XML 元素节点的内容是由一个表达式或一列表达式指定的。 element-content-expression 的数据类型不能是 BINARY 类型, VARBINARY 类型或结构化类型 (SQLSTATE 42884)。 此表达式可以是任意 SQL 表达式。

如果未指定 element-content-expression,那么空字符串将用作元素的内容并且一定不能指定 OPTION NULL ON NULL 或 EMPTY ON NULL。

选项
指定用于构造 XML 元素的其他选项。 如果未指定 OPTION 子句,那么缺省值为 EMPTY ON NULL XMLBINARY USING BASE64。 此子句对 element-content-expression 中指定的嵌套 XMLELEMENT 调用没有影响。
EMPTY ON NULL NULL ON NULL
如果每个 element-content-expression 的值都是空值,那么指定是返回空值还是空元素。 此选项仅影响元素内容的空值处理,而不会影响属性值。 缺省值为 EMPTY ON NULL。
EMPTY ON NULL
如果每个 element-content-expression 的值都为空,那么会返回空元素。
NULL ON NULL
如果每个 element-content-expression 的值为空,那么会返回空值。
XMLBINARY USING BASE64 XMLBINARY USING HEX
指定二进制输入数据的采用编码、带有 FOR BIT DATA 属性的字符串或基于其中一种类型的单值类型。 该编码适用于元素内容或属性值。 缺省值为 XMLBINARY USING BASE64。
XMLBINARY USING BASE64
根据对 XML 模式类型 xs:base64Binary 编码的定义,指定采用编码为基本 64 位字符。 基本 64 位代码使用 US-ASCII 的由 65 个字符组成的子集(10 个数字、26 个小写字符、26个大写字符以及“+”和“/”)来表示每个二进制数据或位数据的 6 位以及子集中的一个可打印字符。 这些字符已被选中,所以它们是以可通用的方式表示的。 使用此方法时,编码数据的大小比原始二进制数据或位数据大 33%。
XMLBINARY USING HEX
根据对 XML 模式类型 xs:hexBinary 编码的定义,指定采用编码为十六进制字符。 十六进制编码使用两个十六进制字符来表示每个字节(8 位)。 使用此方法时,编码数据的大小是原始二进制数据或位数据的两倍。

此函数使用元素名称、名称空间声明的可选集合、属性的可选集合以及零个或多个自变量来构成 XML 元素的内容。 结果是包含 XML 元素或空值的 XML 序列。

结果的数据类型为 XML。 如果任何 element-content-expression 自变量可为空,那么结果可为空;如果所有 element-content-expression 自变量值为空并且 NULL ON NULL 选项生效,那么结果为空。

注意

  • 构造将作为另一元素(用于定义缺省名称空间)的内容进行复制的元素时,应在被复制元素中显式取消声明缺省名称空间,以避免因为从新的父代元素继承缺省名称空间而可能导致的错误。 预定义名称空间前缀(“xs”、“xsi”、“xml”和“sqlxml”)在使用时也必须显式声明。
  • 构造元素节点:生成的元素节点按如下方式构造:
    1. xmlnamespaces-declaration 将对已构造元素添加一组名称空间作用域。 每个名称空间作用域会将名称空间前缀(或缺省名称空间)与名称空间 URI 相关联。 名称空间作用域将定义一组名称空间前缀,这些前缀可用于解释元素作用域内的 QNames。
    2. 如果指定了 xmlattributes-function,那么会对其求值,结果是属性节点序列。
    3. 将对每个 element-content-expression 求值,结果将转换为如下所示的节点序列:
      • 如果结果类型不是 XML ,那么会将其转换为 XML 文本节点,该节点的内容是根据 将 SQL 数据值映射到 XML 数据值 (请参阅 数据类型之间的强制类型转换中描述从非 XML 值到 XML 值的受支持强制类型转换的表)的规则映射到 XML 的 元素-内容-表达式 的结果。
      • 如果结果类型为 XML,那么一般来说结果是项序列。 该序列中的某些项可能是文档节点。 序列中的每个文档节点将替换为其顶级子代序列。 对于结果序列中的每个节点,将为该节点构造新的深层副本,包括其子代和属性。 每个复制节点都具有新的节点身份。 被复制元素和属性节点将保留其类型注释。 对于由序列中返回的一个或多个原子值组成的每个相邻序列,将构造新的文本节点(包含将每个原子值强制转换为字符串的结果),并会在相邻值之间插入单个空白字符。 内容序列中的相邻文本节点将通过并置内容(相邻值之间不插入空格)来合并成单个文本节点。 并置后,将从内容序列中删除内容为零长度字符串的任何文本节点。
    4. XML 属性的结果序列和所有 element-content-expression 指定结果序列将并置成为一个序列,称为内容序列。 内容序列中的相邻文本节点的任何序列将合并成单个文本节点。 如果所有 element-content-expression 自变量都是空字符串,或者未指定 element-content-expression 自变量,那么会返回空元素。
    5. 内容序列只能包含后跟属性节点的属性节点 (SQLSTATE 10507)。 内容序列中出现的属性节点将成为新元素节点的属性。 在这些属性节点中,一定不能有两个或两个以上属性节点同名 (SQLSTATE 10503)。 如果名称空间 URI 不在已构造元素的名称空间作用域中,那么将创建对应于属性节点名称中使用的任何名称空间的名称空间声明。
    6. 内容序列中的元素、文本、注释和处理指令将成为已构造元素节点的子代。
    7. 已构造元素节点的类型注释被指定为 xs:anyType,它的每个属性的类型注释被指定为 xdt:untypedAtomic。 已构造元素节点的节点名是在 NAME 关键字之后指定的元素名称。
  • 在 XMLELEMENT 中使用名称空间的规则:考虑下列有关名称空间作用域限定的规则:
    • XMLNAMESPACES 声明中声明的名称空间是由 XMLELEMENT 函数构造的元素节点的名称空间作用域。 如果元素节点已序列化,那么它的每个名称空间作用域将作为名称空间属性序列化,除非它是元素节点父代的名称空间作用域,而父代元素也已序列化。
    • 如果 XMLQUERY 或 XMLEXISTS 在 element-content-expression 中,那么这些名称空间将成为 XMLQUERY 或 XMLEXISTS 的 XQuery 表达式的静态已知名称空间。 静态已知名称空间用于解析 XQuery 表达式中的 QNames。 如果 XQuery 序言在 XQuery 表达式作用域中使用同一前缀声明名称空间,那么序言中声明的名称空间将覆盖 XMLNAMESPACES 声明中声明的名称空间。
    • 如果已构造元素的属性来自 element-content-expression,那么其名称空间可能尚未声明为已构造元素的名称空间作用域,在此情况下,将其为其创建新的名称空间。 如果这将导致冲突,这意味着属性名称的前缀已由作用域内名称空间绑定到另一 URI ,那么将生成不会导致此类冲突的前缀,并且属性名称中使用的前缀将更改为新前缀,并且将为此新前缀创建名称空间。 生成的新前缀将遵循以下模式:“db2ns-xx”,其中“x”是从集合 [A-Z、a-z 和 0-9] 中选择的字符。 例如:
         VALUES XMLELEMENT(
           NAME "c", XMLQUERY(
             'declare namespace ipo="www.ipo.com"; $m/ipo:a/@ipo:b'
               PASSING XMLPARSE(
                 DOCUMENT '<tst:a xmlns:tst="www.ipo.com" tst:b="2"/>'
               ) AS "m"
           )
         )
      返回:
      <c xmlns:tst="www.ipo.com" tst:b="2"/>
      第二个示例:
         VALUES XMLELEMENT(
           NAME "tst:c", XMLNAMESPACES(
             'www.tst.com' AS "tst"
           ),
           XMLQUERY(
             'declare namespace ipo="www.ipo.com"; $m/ipo:a/@ipo:b'
               PASSING XMLPARSE(
                 DOCUMENT '<tst:a xmlns:tst="www.ipo.com" tst:b="2"/>'
               ) AS "m"
           )
         )
      返回:
      <tst:c xmlns:tst="www.tst.com" xmlns:db2ns-a1="www.ipo.com"
        db2ns-a1:b="2"/>

示例

注: XMLELEMENT 不会在输出中插入空格或换行符。 已对所有示例输出进行格式化来增强可读性。
  • 示例 1:使用 NULL ON NULL 选项来构造元素。
       SELECT E.FIRSTNME, E.LASTNAME, XMLELEMENT(
         NAME "Emp", XMLELEMENT(
           NAME "firstname", E.FIRSTNME
         ), 
         XMLELEMENT(
           NAME "lastname", E.LASTNAME
         )
         OPTION NULL ON NULL
       )
       AS "Result"
       FROM EMPLOYEE E
       WHERE E.EDLEVEL = 12
    此查询将生成以下结果:
    FIRSTNME     LASTNAME        Emp
    JOHN         PARKER          <Emp><firstname>JOHN</firstname>
                                   <lastname>PARKER</lastname></Emp>
    MAUDE        SETRIGHT        <Emp><firstname>MAUDE</firstname>
                                   <lastname>SETRIGHT</lastname></Emp>
    MICHELLE     SPRINGER        <Emp><firstname>MICHELLE</firstname>
                                   <lastname>SPRINGER</lastname></Emp>
  • 示例 2:生成带有作为子元素嵌套的元素列表的元素。
       SELECT XMLELEMENT(
         NAME "Department", XMLATTRIBUTES(
           E.WORKDEPT AS "name"
         ),
         XMLAGG(
           XMLELEMENT(
             NAME "emp", E.FIRSTNME
           )
           ORDER BY E.FIRSTNME
         )
       )
       AS "dept_list"
       FROM EMPLOYEE E
       WHERE E.WORKDEPT IN ('A00', 'B01')
       GROUP BY WORKDEPT
    此查询将生成以下结果:
    dept_list
    <Department name="A00">
    <emp>CHRISTINE</emp>
    <emp>SEAN</emp>
    <emp>VINCENZO</emp>
    </Department>
    <Department name="B01">
    <emp>MICHAEL</emp>
    </Department>
  • 示例 3:创建嵌套 XML 元素,指定缺省 XML 元素名称空间并使用子查询。
    SELECT XMLELEMENT(
             NAME "root",
             XMLNAMESPACES(DEFAULT 'http://mytest.uri'),
             XMLATTRIBUTES(cid),
                (SELECT 
                   XMLAGG(
                     XMLELEMENT( 
                       NAME "poid", poid
                     )
                   )
                 FROM purchaseorder
                 WHERE purchaseorder.custid = customer.cid 
                )
           )
    FROM customer 
    WHERE cid = '1002'
    
    该语句返回以下在根元素中声明了缺省元素名称空间的 XML 文档:
    <root xmlns="http://mytest.uri" CID="1002">
      <poid>5000</poid>
      <poid>5003</poid>
      <poid>5006</poid>
    </root>
  • 示例 4:将公共表表达式与 XML 名称空间配合使用。
    通过公共表表达式构造 XML 元素且在同一 SQL 语句的其他地方使用此元素时,任何名称空间声明都应该指定为元素构造的一部分。 以下语句在使用 PURCHASEORDER 表创建 poid 元素的公共表表达式和使用 CUSTOMER 表创建根元素的 SELECT 语句中指定缺省 XML 名称空间。
    WITH tempid(id, elem) AS
      (SELECT custid, XMLELEMENT(NAME "poid", 
         XMLNAMESPACES(DEFAULT 'http://mytest.uri'), 
           poid)
       FROM purchaseorder )
    SELECT XMLELEMENT(NAME "root",
             XMLNAMESPACES(DEFAULT 'http://mytest.uri'),
                XMLATTRIBUTES(cid),
                (SELECT XMLAGG(elem)
                 FROM tempid
                 WHERE tempid.id = customer.cid )
            )
    FROM customer 
    WHERE cid = '1002'
    
    该语句返回以下在根元素中声明了缺省元素名称空间的 XML 文档。
    <root xmlns="http://mytest.uri" CID="1002">
      <poid>5000</poid>
      <poid>5003</poid>
      <poid>5006</poid>
    </root>
    
    在下列语句中,仅在使用 CUSTOMER 表创建根元素的 SELECT 语句中声明缺省元素名称空间:
    WITH tempid(id, elem) AS
        (SELECT custid, XMLELEMENT(NAME "poid", poid)
         FROM purchaseorder )
    SELECT XMLELEMENT(NAME "root",
             XMLNAMESPACES(DEFAULT 'http://mytest.uri'),
                XMLATTRIBUTES(cid),
                (SELECT XMLAGG(elem)
                 FROM tempid
                 WHERE tempid.id = customer.cid )
           )
    FROM customer 
    WHERE cid = '1002'
    
    该语句返回以下在根元素中声明了缺省元素名称空间的 XML 文档。 因为在公共表表达式中创建 poid 元素而没有声明缺省元素名称空间,所以未定义 poid 元素的缺省元素名称空间。 在 XML 文档中,由于未定义 poid 元素的缺省元素名称空间,并且 poid 元素不属于根元素 xmlns="http://mytest.uri" 的缺省元素名称空间,所以 poid 元素的缺省元素名称空间设置为空字符串 ""。
    <root xmlns="http://mytest.uri" CID="1002">
      <poid xmlns="">5000</poid>
      <poid xmlns="">5003</poid>
      <poid xmlns="">5006</poid>
    </root>