在PLSQL中,我进行soap调用,并从SOAP接收XML结果。 我需要检索元素值。
这在这个XML上运行良好:
<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:executeObjectResponse xmlns:ns2="http://www.uc4.com/uc4/">
<runID>1120864</runID>
</ns2:executeObjectResponse>
</S:Body>
</S:Envelope>
使用此代码:
declare
v_doc DBMS_XMLDOM.DOMDocument;
v_Value VARCHAR2 (2000);
v_node DBMS_XMLDOM.DOMNode;
v_nodelist DBMS_XMLDOM.DOMNodelist;
begin
... XML result from soap call catched in CLOB => l_result
v_doc := DBMS_XMLDOM.newdomdocument (l_result);
v_nodelist := DBMS_XMLDOM.getelementsbytagname (v_doc, 'runID');
v_node := DBMS_XMLDOM.getfirstchild (DBMS_XMLDOM.item (v_nodelist, 0));
v_value := DBMS_XMLDOM.getnodevalue (v_node);
DBMS_OUTPUT.put_line ('value a: ' || v_Value);
value a: 1120864
但我确实遇到以下XML问题。 我需要检索此标记的值:
<name>&RESULT#</name>
我尝试了几件事,但却找不到适当的代码。
SOAP的结果我在CLOB(l_result)中捕获。
<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:getTaskDetailsResponse xmlns:ns2="http://www.uc4.com/uc4/">
<groups>
<name>General</name>
<label>SCRI.ADP.SOAP.TEST (1120864)</label>
<items>
<name>Object name</name>
<value>SCRI.ADP.SOAP.TEST</value>
</items>
<items>
<name>Queue</name>
<value>CLIENT_QUEUE</value>
</items>
<items>
<name>Version</name>
<value>6</value>
</items>
<items>
<name>RunID</name>
<value>1120864</value>
</items>
<items>
<name>Activator</name>
<value>1115216</value>
</items>
<items>
<name>User</name>
<value>ADP_SOAP/ADP</value>
</items>
<items>
<name>Activation</name>
<value>2017-05-24T13:38:44</value>
</items>
<items>
<name>Start</name>
<value>2017-05-24T13:38:45</value>
</items>
<items>
<name>End</name>
<value>2017-05-24T13:38:45</value>
</items>
<items>
<name>Runtime</name>
<value>0:00:00</value>
</items>
<items>
<name>Status</name>
<value>ENDED_OK - ended normally</value>
</items>
<items>
<name>Return code</name>
<value>0</value>
</items>
<items>
<name>Event ID</name>
<value>1120864</value>
</items>
<items>
<name>Enable Rollback</name>
<value>No</value>
</items>
</groups>
<groups>
<name>Object variables</name>
<label>SCRI.ADP.SOAP.TEST (1120864)</label>
<items>
<name>&EXT_HOSTNAME#</name>
<value>sz4183</value>
</items>
<items>
<name>&EXT_SOAP_ID#</name>
<value>sz4183</value>
</items>
<items>
<name>&EXT_SOAP_WF#</name>
<value>JOBP.ADP.SOAP_TEST1</value>
</items>
<items>
<name>&RESULT#</name>
<value>/dev;/u01;/etc/mnttab;/etc/dfs/sharetab;/dev/fd;/export;/rpool;/mnt/ora_dba</value>
</items>
</groups>
</ns2:getTaskDetailsResponse>
</S:Body>
</S:Envelope>
我玩弄了这个,但没有成功:
declare
v_doc DBMS_XMLDOM.DOMDocument;
v_Value VARCHAR2 (2000);
v_node DBMS_XMLDOM.DOMNode;
v_nodelist DBMS_XMLDOM.DOMNodelist;
begin
... XML result from soap call catched in CLOB => l_result
v_doc := DBMS_XMLDOM.newdomdocument (l_result);
v_nodelist := DBMS_XMLDOM.getelementsbytagname (v_doc, '&RESULT#');
v_node := DBMS_XMLDOM.getfirstchild (DBMS_XMLDOM.item (v_nodelist, 0));
v_value := DBMS_XMLDOM.getnodevalue (v_node);
DBMS_OUTPUT.put_line ('value: ' || v_Value);
end;
欢迎所有的消遣。
欢呼声 维姆
答案 0 :(得分:0)
我发现代码有效。
dbms_xmldom.freeDocument(v_doc);
v_doc := DBMS_XMLDOM.newdomdocument (l_result);
v_nodelist := DBMS_XMLDOM.getelementsbytagname (v_doc, 'name');
v_node := DBMS_XMLDOM.getfirstchild (DBMS_XMLDOM.item (v_nodelist, 19));
v_value := DBMS_XMLDOM.getnodevalue (v_node);
DBMS_OUTPUT.put_line ('name: ' || v_Value);
v_nodelist := DBMS_XMLDOM.getelementsbytagname (v_doc, 'value');
v_node := DBMS_XMLDOM.getfirstchild (DBMS_XMLDOM.item (v_nodelist, 17));
v_value := DBMS_XMLDOM.getnodevalue (v_node);
DBMS_OUTPUT.put_line ('value : ' || v_Value);
结果是:
name: &RESULT#
value : /dev;/u01;/etc/mnttab;/etc/dfs/sharetab;/dev/fd;/export;/rpool;/mnt/ora_dba
我还想找到的是如何搜索元素&amp; RESULT#以及属于该元素的值。 现在我确实计算了元素(名称为19,值为17),只是为了检查代码。
欢呼Wim
答案 1 :(得分:0)
我根本不会尝试遍历DOM,但我想你可以迭代items
个节点,测试每个节点中的name
文本,当你找到那个节点时停止对此感兴趣 - 然后使用items
节点的value
文本。
虽然使用内置的XML处理更容易:
declare
l_result clob := '... your SOAP response ...';
v_Value VARCHAR2 (2000);
begin
select xmlquery('//items/name[text()=''&RESULT#'']/../value/text()'
passing xmltype(l_result)
returning content).getstringval()
into v_Value
from dual;
DBMS_OUTPUT.put_line ('value: ' || v_Value);
end;
/
value: /dev;/u01;/etc/mnttab;/etc/dfs/sharetab;/dev/fd;/export;/rpool;/mnt/ora_dba
PL/SQL procedure successfully completed.
你可以read more about XMLQuery in the documentation。在这种情况下我使用的XPath:
//items/name[text()=''&RESULT#'']/../value/text()
查找items/name
节点,其文本值是您想要的字符串(在转义的单引号中);然后使用items
找到它的父(..
)节点,然后在 values
节点下找到items
节点。并获得其文本值。
(可能最好提供items
节点的完整路径,并包含所有命名空间信息,但您可以添加它;使用//items
忽略上面的结构。)< / p>
你也可以用你的第一个例子做同样的事情,顺便说一下:
...
begin
select xmlquery('//runID/text()'
passing xmltype(l_result)
returning content).getstringval()
into v_Value
from dual;
DBMS_OUTPUT.put_line ('value a: ' || v_Value);
end;
/
value a: 1120864
PL/SQL procedure successfully completed.