【问题标题】:ORACLE 12c XML: Extract value from XML string using EXTRACTVALUEORACLE 12c XML:使用 EXTRACTVALUE 从 XML 字符串中提取值
【发布时间】:2015-11-04 18:40:06
【问题描述】:

感谢您在这方面的帮助..

我有一个 XML 字符串包含在一个 XMLType 中,我试图从中提取一个值。基于大量在线研究,我已经花了很长时间,但没有成功...

l_resp_xml (xmltype) 中保存的字符串是:

<ns1:validateAccountResponse 
xmlns:ns1="https://ws.hyphen.co.za/accountvalidation2">
<return xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xsi:type="tns:WebService_AccountValidation_Response">
     <reference xsi:type="xsd:string">TLPM165U2876100975</reference>
     <branchCode xsi:type="xsd:string">187646</branchCode>
     <bankName xsi:type="xsd:string">NED:NEDBANK LTD RSA</bankName>
     <branchName xsi:type="xsd:string">NEDBANK BRITS</branchName>
     <accountNumber xsi:type="xsd:string">00000002876100975</accountNumber>
     <accountType xsi:type="xsd:string">2</accountType>
     <errorCode xsi:type="xsd:string">0</errorCode>
     <resultCode xsi:type="xsd:string">0000</resultCode>
     <resultMessage xsi:type="xsd:string"/>
     <checkSum xsi:type="xsd:string">db8d375002ca1e62ab4e8696c480df12d7e10293a29ba1a0dc99868d18    aa2c7e</checkSum>
</return></ns1:validateAccountResponse>

我尝试了很多不同的方法来获取 bankName 的值。最新的很简单:

         SELECT 
         EXTRACTVALUE(l_resp_xml, '/return/bankName')
         into l_bank_name
     FROM DUAL; 

我尝试了很多变体,但无法从 bankName 获取值(l_bank_name 的内容始终为空白。如果有人可以提供帮助,我将不胜感激

非常感谢 理查德

【问题讨论】:

    标签: xml oracle


    【解决方案1】:

    EXTRACTVALUE 一直是deprecated for some time。您应该使用XQuery,在这种情况下,使用 XMLQuery 的单个简单路径;加上你需要引用命名空间ns1,而你忽略了顶级节点validateAccountResponse:

    with t (l_resp_xml) as (
      select xmltype('<ns1:validateAccountResponse 
    xmlns:ns1="https://ws.hyphen.co.za/accountvalidation2">
    <return xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xsi:type="tns:WebService_AccountValidation_Response">
         <reference xsi:type="xsd:string">TLPM165U2876100975</reference>
         <branchCode xsi:type="xsd:string">187646</branchCode>
         <bankName xsi:type="xsd:string">NED:NEDBANK LTD RSA</bankName>
         <branchName xsi:type="xsd:string">NEDBANK BRITS</branchName>
         <accountNumber xsi:type="xsd:string">00000002876100975</accountNumber>
         <accountType xsi:type="xsd:string">2</accountType>
         <errorCode xsi:type="xsd:string">0</errorCode>
         <resultCode xsi:type="xsd:string">0000</resultCode>
         <resultMessage xsi:type="xsd:string"/>
         <checkSum xsi:type="xsd:string">db8d375002ca1e62ab4e8696c480df12d7e10293a29ba1a0dc99868d18    aa2c7e</checkSum>
    </return></ns1:validateAccountResponse>') from dual
    )
    SELECT XMLQuery('declare namespace ns1 = "https://ws.hyphen.co.za/accountvalidation2"; (::)
        /ns1:validateAccountResponse/return/bankName/text()'
      PASSING l_resp_xml RETURNING CONTENT) AS bankName
    FROM t;
    
    BANKNAME                                                                       
    --------------------------------------------------------------------------------
    NED:NEDBANK LTD RSA
    

    或者使用您的 PL/SQL 值:

    SELECT CAST(XMLQuery('declare namespace ns1 = "https://ws.hyphen.co.za/accountvalidation2"; (::)
        /ns1:validateAccountResponse/return/bankName/text()'
      PASSING l_resp_xml RETURNING CONTENT) AS VARCHAR2(30))
    INTO l_bank_name
    FROM dual;
    

    您还可以使用 XMLTable 更轻松地提取多个值,尤其是当您从表中的行中获取多个 XMLType 值时:

    with t (l_resp_xml) as (
      select xmltype('<ns1:validateAccountResponse 
    xmlns:ns1="https://ws.hyphen.co.za/accountvalidation2">
    <return xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xsi:type="tns:WebService_AccountValidation_Response">
         <reference xsi:type="xsd:string">TLPM165U2876100975</reference>
         <branchCode xsi:type="xsd:string">187646</branchCode>
         <bankName xsi:type="xsd:string">NED:NEDBANK LTD RSA</bankName>
         <branchName xsi:type="xsd:string">NEDBANK BRITS</branchName>
         <accountNumber xsi:type="xsd:string">00000002876100975</accountNumber>
         <accountType xsi:type="xsd:string">2</accountType>
         <errorCode xsi:type="xsd:string">0</errorCode>
         <resultCode xsi:type="xsd:string">0000</resultCode>
         <resultMessage xsi:type="xsd:string"/>
         <checkSum xsi:type="xsd:string">db8d375002ca1e62ab4e8696c480df12d7e10293a29ba1a0dc99868d18    aa2c7e</checkSum>
    </return></ns1:validateAccountResponse>') from dual
    )
    SELECT x.reference, x.bankname, x.branchCode
    FROM t
    CROSS JOIN XMLTABLE(
      XMLNAMESPACES('https://ws.hyphen.co.za/accountvalidation2' as "ns1"),
      '/ns1:validateAccountResponse/return'
      PASSING t.l_resp_xml
      COLUMNS reference VARCHAR2(20) PATH 'reference',
        bankName VARCHAR2(30) PATH 'bankName',
        branchCode NUMBER PATH 'branchCode'
    ) x;
    
    REFERENCE            BANKNAME                       BRANCHCODE
    -------------------- ------------------------------ ----------
    TLPM165U2876100975   NED:NEDBANK LTD RSA                187646
    

    【讨论】:

    • 谢谢 Alex,在网上找到示例代码的危险...这是否意味着 Extract 也被贬值了?我正在使用 l_resp_xml := xmltype.createxml(l_clob_response); -- 清除 SOAP 标头 SELECT extract(l_resp_xml ,'Envelope/Body/node()' ,l_namespace_soap) INTO l_resp_xml FROM dual;从 SOAP 信封中检索 XML 片段..
    • Yes, it is。您也可以为此使用 XQuery。或者只是在单个 XQuery 中包含 Envelope/Body 和 SOAP 名称空间以及返回值。
    • @RichardLegge - this answer 正在从 SOAP 信封中提取数据;非常相似的想法并展示了两个命名空间。
    • 好东西谢谢。刚刚开始工作.. 非常感谢您的意见。赞赏。
    【解决方案2】:

    虽然EXTRACTVALUE 已被弃用,但这将是带有EXTRACTVALUE 的版本:

    SELECT 
        EXTRACTVALUE(l_resp_xml, '/ns1:validateAccountResponse/return/bankName', 'xmlns:ns1="https://ws.hyphen.co.za/accountvalidation2"')
    INTO l_bank_name
    FROM dual;
    

    但XMLTable 或XMLQuery 是首选方式。

    【讨论】:

      猜你喜欢
      • 2021-08-10
      • 2013-05-02
      • 2013-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-28
      • 1970-01-01
      • 2018-02-23
      相关资源
      最近更新 更多