![](/img/trans.png)
[英]How to select a particular Node name in XML using Oracle SQL query?
[英]How to select a particular Node name and its values in XML using Oracle SQL query?
我有一個名為SOAP_MONITORING的表,其中有RESPONSE_XML列,它是CLOB數據類型。 在此列中,存儲了較大的xml字符串。 我想從此xml字符串中獲取節點名稱和節點值。 這是我的xml:
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><ns:placeShopOrderResponse xmlns:ns="http://service.soap.CDRator.com">
<ns:return xmlns:ax2133="http://signup.data.soap.CDRator.com/xsd" xmlns:ax2134="http://core.signup.data.soap.CDRator.com/xsd" xmlns:ax2127="http://data.soap.CDRator.com/xsd" xmlns:ax2129="http://webshop.data.soap.CDRator.com/xsd" xmlns:ax2130="http://core.data.soap.CDRator.com/xsd" xmlns:ax2140="http://core.result.service.soap.CDRator.com/xsd" xmlns:ax2139="http://result.service.soap.CDRator.com/xsd" xmlns:ax2147="http://webshop.result.service.soap.CDRator.com/xsd" xmlns:ax2148="http://mandate.result.service.soap.CDRator.com/xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ax2147:PlaceShopOrderResultDTO">
<ax2130:id xsi:nil="true" /><ax2140:description>SOAP_GLOBAL_SUCCESS</ax2140:description>
<ax2147:subscriptions xsi:type="ax2127:SubscriptionDTO"><ax2130:id>201501070917439804</ax2130:id>
<ax2130:id>201501070917439804</ax2130:id>
</ns:return></ns:placeShopOrderResponse>
</soapenv:Body>
</soapenv:Envelope>
我想查詢此列以獲得SUBSCRIPTION_ID
,即201501070917439804
。 我嘗試了上面的查詢
SELECT extractvalue(RESPONSE_XML, '/*/ax2130/*/id/@value')
FROM SOAP_MONITORING where WEB_SERVICE_NAME='RatorWebShopService' and WEB_METHOD_NAME='placeShopOrder'
但收到一個錯誤
ORA-00932: inconsistent datatypes: expected - got -
00932. 00000 - "inconsistent datatypes: expected %s got %s"
為了執行此類查詢以從xml獲取節點值,我非常新。
您可以將CLOB轉換為XMLType(假設它是有效的),只需執行以下操作:
extractvalue(XMLType(RESPONSE_XML), ...
不知道為什么要在其中存儲XML的列類型不是XMLType,但這並不完全相關。
然后,您可以將名稱空間提供給extractvalue()
:
SELECT extractvalue(XMLType(RESPONSE_XML),
'//ax2130:id/text()',
'xmlns:ax2130="http://core.data.soap.CDRator.com/xsd"')
FROM SOAP_MONITORING
where WEB_SERVICE_NAME='RatorWebShopService' and WEB_METHOD_NAME='placeShopOrder';
..但您有多個ID,因此得到: ORA-19025: EXTRACTVALUE returns value of only one node
。
如文檔中所述 ,不建議使用extractvalue
您可以改用XQuery ,特別是XMLTable。
假設只需要將ax2130:id
值嵌套在ax2147:subscription
,則可以使用以下XQuery:
SELECT xt.id
FROM SOAP_MONITORING sm
CROSS JOIN XMLTable(XMLNAMESPACES (
'http://schemas.xmlsoap.org/soap/envelope/' AS "soapenv",
'http://service.soap.CDRator.com' as "ns",
'http://core.data.soap.CDRator.com/xsd' as "ax2130",
'http://webshop.result.service.soap.CDRator.com/xsd' as "ax2147"
),
'for $i in /soapenv:Envelope/soapenv:Body/ns:placeShopOrderResponse/ns:return/ax2147:subscriptions
return $i/ax2130:id'
passing XMLType(sm.RESPONSE_XML)
columns "ID" number path '/') xt
where WEB_SERVICE_NAME='RatorWebShopService' and WEB_METHOD_NAME='placeShopOrder';
ID
---------------------
201501070917439804
201501070917439804
2 rows selected
或者,如果您想在任何地方都需要ax:2130
節點,包括空白節點,則可以使用:
SELECT xt.id
FROM SOAP_MONITORING sm
CROSS JOIN XMLTable(XMLNAMESPACES (
'http://core.data.soap.CDRator.com/xsd' as "ax2130"
),
'for $i in //ax2130:id return $i'
passing XMLType(sm.RESPONSE_XML)
columns "ID" number path '/') xt
where WEB_SERVICE_NAME='RatorWebShopService' and WEB_METHOD_NAME='placeShopOrder';
ID
---------------------
201501070917439804
201501070917439804
3 rows selected
僅需要在XMLNamespaces子句中指定XQuery中引用的名稱空間。
如果需要,您可以基於所選的ID聯接到另一個表:
SELECT xt.id
FROM SOAP_MONITORING sm
CROSS JOIN XMLTable(XMLNAMESPACES (
...) xt
JOIN someothertable sot on sot.id = xt.id
where sm.WEB_SERVICE_NAME='RatorWebShopService'
and sm.WEB_METHOD_NAME='placeShopOrder';
做:
"SELECT extractvalue(XMLTYPE(RESPONSE_XML), '/*/ax2130/*/id/@value')
FROM SOAP_MONITORING where WEB_SERVICE_NAME='RatorWebShopService' and WEB_METHOD_NAME='placeShopOrder'"
代替:
SELECT extractvalue(RESPONSE_XML, '/*/ax2130/*/id/@value')
FROM SOAP_MONITORING where WEB_SERVICE_NAME='RatorWebShopService' and WEB_METHOD_NAME='placeShopOrder'
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.