Oracle Pl/SQL:循环通过 XMLTYPE 节点

Posted

技术标签:

【中文标题】Oracle Pl/SQL:循环通过 XMLTYPE 节点【英文标题】:Oracle Pl/SQL: Loop through XMLTYPE nodes 【发布时间】:2010-11-02 10:07:47 【问题描述】:

我有一个包含以下内容的 XMLTYPE:

<?xml version="1.0"?>
    <users>
        <user>
            <name>user1</name>
        </user>
        <user>
            <name>user2</name>
        </user>
        <user>
            <name>user3</name>
        </user>
    </users>

如何在 PL/SQL 中循环遍历所有“用户”元素?谢谢

【问题讨论】:

【参考方案1】:

您可以使用 EXTRACTXMLSequence 循环遍历元素(将 XML 拆分为不同的块 - 这里是用户),如下所示:

SQL> SELECT extractvalue(column_value, '/user/name') "user"
  2    FROM TABLE(XMLSequence(XMLTYPE(
  3                 '<?xml version="1.0"?>
  4                     <users>
  5                         <user>
  6                             <name>user1</name>
  7                         </user>
  8                         <user>
  9                             <name>user2</name>
 10                         </user>
 11                         <user>
 12                             <name>user3</name>
 13                         </user>
 14                     </users>').extract('/users/user'))) t;

user
--------
user1
user2
user3

【讨论】:

【参考方案2】:

您可以使用 XQuery。查看下面的选择语句。 v_xml_doc 是包含 XML 数据的 XMLTYPE 变量。

select name
from   XMLTable('for $i in /users/user
                            return $i'
                            passing   v_xml_doc
                            columns   name varchar2(200) path 'name'
               )

【讨论】:

【参考方案3】:

这个怎么样:

PROCEDURE xmltest IS
  v_userlist XMLType;
  v_count NUMBER(38) := 1;
BEGIN
  /* define XML variable */
  v_userlist := XMLType('<?xml version="1.0"?>
    <users>
        <user>
            <name>user1</name>
        </user>
        <user>
            <name>user2</name>
        </user>
        <user>
            <name>user3</name>
        </user>
    </users>');

  /* for each user, print out their name (each element can be extracted using xpath '//user[1]' '//user[2]' etc) */
  WHILE v_userlist.existsNode('//user[' || v_count || ']') = 1 LOOP
    dbms_output.put_line(v_userlist.extract('//user[' || v_count || ']/name/text()').getStringVal());
    v_count := v_count + 1;
  END LOOP;
END;

【讨论】:

【参考方案4】:
select xt.* from xmltable('/users/user' passing xmltype('<users>
    <user>
        <name>user1</name>
    </user>
    <user>
        <name>user2</name>
    </user>
    <user>
        <name>user3</name>
    </user>
</users>') columns name varchar2(10) path 'name' ) xt 

【讨论】:

【参考方案5】:
ITS VERY GOOD!!

CADENA   CLOB;
BEGIN
   SELECT CASE
             WHEN EXISTSNODE (:NEW.MENSAJE, '/Body') <> 0 THEN 'ERROR'
             ELSE NULL
          END
     INTO :NEW.DESCRIPCION_ERROR
     FROM DUAL;

   CADENA := :NEW.MENSAJE.EXTRACT ('/Body/xmlOriginal/text()').getStringVal ();
   CADENA := REPLACE (CADENA, '&lt;', '<');
   CADENA := REPLACE (CADENA, '&gt;', '>');

【讨论】:

以上是关于Oracle Pl/SQL:循环通过 XMLTYPE 节点的主要内容,如果未能解决你的问题,请参考以下文章

Oracle笔记4-pl/sql-分支/循环/游标/异常/存储/调用/触发器

循环在尝试通过 Oracle EBS 中的并发程序使用 PL/SQL 创建 XML 时提前结束

Oracle PL/SQL 在循环中捕获锁定异常并继续

Oracle——PL/SQL

oracle pl/sql 控制结构(分支,循环,控制)

循环字符串时如何插入临时表 - Oracle - PL/SQL