2009-06-12 92 views
33

tengo un XmlType con el siguiente contenido:Oracle PL/SQL: Bucle a través de nodos XmlType

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

Cómo puedo bucle en PL/SQL a través de todos los elementos de "usuario"? Gracias

Respuesta

18

puede recorrer los elementos que utilizan EXTRACT y XMLSequence (divide el XML en trozos distintos usuarios) - aquí como este:

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 
+0

muchas gracias! – Samson

15

Puede usar XQuery. Echa un vistazo a la declaración de selección a continuación. v_xml_doc es la variable XMLTYPE que contiene los datos XML.

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

Qué tal esto:

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; 
-2
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;', '>'); 
1
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