Как можно в цикле получить все элементы последовательности?
Есть XMLTYPE со следующим содержимым:
userlist XMLType := XMLType(<?xml version="1.0"?>
<users>
<user>
<name>user1</name>
</user>
<user>
<name>user2</name>
</user>
<user>
<name>user3</name>
</user>
</users>');
Как можно в PL/SQL блоке циклом получить все элементы user?
Можно найти много решений с XMLTable, но это SQL функция и для PL/SQL интерпретатора она не известна.
declare xtab XMLTable;
begin null;
end;
/
PLS-00201: identifier 'XMLTABLE' must be declared
Свободный перевод вопроса Oracle Pl/SQL: Loop through XMLTYPE nodes от участника @pistacchio
Ответы (2 шт):
Автор решения: 0xdb
→ Ссылка
Для простых задач можно воспользоваться функциями самого XMLTYPE:
declare
ul XMLType := XMLType('<?xml version="1.0"?>
<users>
<user id="111">
<name>user1</name>
</user>
<user id="222">
<name>user2</name>
</user>
<user id="333">
<name>user3</name>
</user>
</users>');
counter int := 1;
BEGIN
dbms_output.put_line ('users:');
while ul.existsNode ('//user['||counter||']') = 1 loop
dbms_output.put_line (
' id='||ul.extract ('//user['||counter||']/@id').getNumberVal()||
' name='||ul.extract ('//user['||counter||']/name/text()').getStringVal());
counter := counter+1;
end loop;
end;
/
Результат
users:
id=111 name=user1
id=222 name=user2
id=333 name=user3
Автор решения: 0xdb
→ Ссылка
Для больших XML документов со сложной структурой для повышения производительности рекомендуется воспользоваться программным интерфейсом PL/SQL DOM API for XMLType.
В вопросе представлен простой документ, но только для примера:
declare
xml XMLType := XMLType('<?xml version="1.0"?>
<users>
<user id="111">
<name>user1</name>
</user>
<user id="222">
<name>user2</name>
</user>
<user id="333">
<name>user3</name>
</user>
</users>');
dom dbms_xmldom.domdocument := dbms_xmldom.newdomdocument (xmldoc=>xml);
userlist dbms_xmldom.domnodelist;
usernode dbms_xmldom.domnode;
begin
userlist := dbms_xmldom.getElementsByTagName (dom, 'user');
dbms_output.put_line ('users:');
for ui in 0..dbms_xmldom.getLength (userlist)-1 loop
usernode := dbms_xmldom.item (userlist, ui);
dbms_output.put_line (' id=' ||
dbms_xmldom.getAttribute (dbms_xmldom.makeElement(usernode), 'id')||
' user='||
dbms_xmldom.getNodeValue (dbms_xmldom.getFirstChild (
dbms_xmldom.getFirstChild (usernode ))));
end loop;
dbms_xmldom.freeDocument (dom);
end;
/
Результат:
users:
id=111 user=user1
id=222 user=user2
id=333 user=user3