问题
Below is a typical SOAP request in table 'external'.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<settleResponse xmlns="urn:ABC">
<settleReturn xmlns="">
<message>Missing first name</message>
<errorCode>INVALID_ACC</errorCode>
<customData>offendingTransactionID=12345678</customData>
<divisionRequestID xsi:nil="true"/>
<status>Failed</status>
</settleReturn>
</settleResponse>
</soapenv:Body>
</soapenv:Envelope>
I need to retrieve parameters errorCode, status... and save them in to a DB table. How can I do that?
回答1:
You could extract the node contents with XMLQUERY
:
select xmlquery('declare namespace soapenv = "http://schemas.xmlsoap.org/soap/envelope/";
declare namespace urn = "urn:ABC";
/soapenv:Envelope/soapenv:Body/urn:settleResponse/settleReturn/message/text()'
passing XMLType(message)
returning content) as message,
xmlquery('declare namespace soapenv = "http://schemas.xmlsoap.org/soap/envelope/";
declare namespace urn = "urn:ABC";
/soapenv:Envelope/soapenv:Body/urn:settleResponse/settleReturn/errorCode/text()'
passing XMLType(message)
returning content) as errorCode,
xmlquery('declare namespace soapenv = "http://schemas.xmlsoap.org/soap/envelope/";
declare namespace urn = "urn:ABC";
/soapenv:Envelope/soapenv:Body/urn:settleResponse/settleReturn/status/text()'
passing XMLType(message)
returning content) as status
from external;
MESSAGE ERRORCODE STATUS
-------------------- -------------------- ----------
Missing first name INVALID_ACC Failed
Or perhaps more simply, particularly if you have multiple messages to handle, with XMLTABLE
:
select x.*
from external ext
cross join xmltable(
xmlnamespaces('http://schemas.xmlsoap.org/soap/envelope/' as "soapenv",
'urn:ABC' as "urn"),
'/soapenv:Envelope/soapenv:Body/urn:settleResponse/settleReturn'
passing XMLType(ext.message)
columns message varchar2(20) path 'message',
errorCode varchar2(20) path 'errorCode',
status varchar2(10) path 'status'
) x;
MESSAGE ERRORCODE STATUS
-------------------- -------------------- ----------
Missing first name INVALID_ACC Failed
In both cases you need to specify the namespaces, and the syntax is different. Read more about using these functions.
You can insert those directly into another table with insert into some_table (x, y, z) select ...
.
来源:https://stackoverflow.com/questions/32440074/parse-soap-xml-in-oracle-with-example