【问题标题】:Test whether value exists (node exists?) in xmltype variable (not in table) in PL/SQL在 PL/SQL 的 xmltype 变量(不在表中)中测试值是否存在(节点存在?)
【发布时间】:2021-07-03 19:40:03
【问题描述】:

我有一个来自 PL/SQL 中的 SOAP 调用的结果变量,我得到的输出类型变量是 xmltype(没有编写包或过程,不要更改它)。我得到的变量类型是xmltype,我想检查是否有结果。我无法理解 PL/SQL 中有关 XML 的文档。

帐号将永远存在,我正在检查的是位置是否已返回。或者不止一个被退回(这很糟糕,但我应该检查一下)。

结果看起来像

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing">
   <env:Header>
      <wsa:Action>http://xmlns.oracle.com/apps/cdm/foundation/parties/customerAccountService/applicationModule//CustomerAccountService/findCustomerAccountResponse</wsa:Action>
      <wsa:MessageID>urn:uuid:7dd64ecf-676f-4667-a761-dc7603e99929</wsa:MessageID>
   </env:Header>
   <env:Body>
      <ns0:findCustomerAccountResponse xmlns:ns0="http://xmlns.oracle.com/apps/cdm/foundation/parties/customerAccountService/applicationModule/types/">
         <ns0:result xsi:type="ns2:CustomerAccountResult" xmlns:ns2="http://xmlns.oracle.com/apps/cdm/foundation/parties/customerAccountService/" xmlns:ns1="http://xmlns.oracle.com/adf/svc/types/" xmlns:ns4="http://xmlns.oracle.com/apps/cdm/foundation/parties/partyService/" xmlns:tns="http://xmlns.oracle.com/adf/svc/errors/" xmlns:ns9="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccount/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <ns1:Message>
               <tns:code>25089</tns:code>
               <tns:message>JBO-25089: Too many matching records found. Specify additional criteria to limit the number of records.</tns:message>
               <tns:severity>SEVERITY_WARNING</tns:severity>
            </ns1:Message>
            <ns2:Value>
               <ns2:AccountNumber>XXXXX</ns2:AccountNumber>
               <ns2:CustomerAccountSite xmlns:ns7="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccountSite/"/>
               <ns2:CustomerAccountSite xmlns:ns7="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccountSite/">
                  <ns2:CustomerAccountSiteUse xmlns:ns6="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccountSiteUse/">
                     <ns2:Location>XXXXXXXX</ns2:Location>
                  </ns2:CustomerAccountSiteUse>
               </ns2:CustomerAccountSite>
               <ns2:CustomerAccountSite xmlns:ns7="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccountSite/"/>
               <ns2:CustomerAccountSite xmlns:ns7="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccountSite/"/>
            </ns2:Value>
         </ns0:result>
      </ns0:findCustomerAccountResponse>
   </env:Body>
</env:Envelope>

我觉得有点像

IF DBMS_LOB.INSTR(xml_response.getClobVal(), 'Location>XXXXXX<') > 0 THEN
     val_returned := TRUE;
END IF;

可行,但我认为这可能是一种不好的做法?我一直在尝试阅读文档,但它们都引用了从表格等中进行选择,而我没有表格。我可以在不引用表格的情况下在这些东西上使用 xml 表达式吗?我必须从双重或其他中选择吗?

【问题讨论】:

    标签: xml oracle soap plsql


    【解决方案1】:

    是的,Oracle 中的 XPath 并不漂亮,尤其是在涉及名称空间的情况下。我不擅长,但也许这会让你朝着正确的方向开始:

    DECLARE
      accountnumber VARCHAR2(100);
      location      VARCHAR2(100);
      x XMLType := XMLType('
    <env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing">
       <env:Header>
          <wsa:Action>http://xmlns.oracle.com/apps/cdm/foundation/parties/customerAccountService/applicationModule//CustomerAccountService/findCustomerAccountResponse</wsa:Action>
          <wsa:MessageID>urn:uuid:7dd64ecf-676f-4667-a761-dc7603e99929</wsa:MessageID>
       </env:Header>
       <env:Body>
          <ns0:findCustomerAccountResponse xmlns:ns0="http://xmlns.oracle.com/apps/cdm/foundation/parties/customerAccountService/applicationModule/types/">
             <ns0:result xsi:type="ns2:CustomerAccountResult" xmlns:ns2="http://xmlns.oracle.com/apps/cdm/foundation/parties/customerAccountService/" xmlns:ns1="http://xmlns.oracle.com/adf/svc/types/" xmlns:ns4="http://xmlns.oracle.com/apps/cdm/foundation/parties/partyService/" xmlns:tns="http://xmlns.oracle.com/adf/svc/errors/" xmlns:ns9="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccount/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                <ns1:Message>
                   <tns:code>25089</tns:code>
                   <tns:message>JBO-25089: Too many matching records found. Specify additional criteria to limit the number of records.</tns:message>
                   <tns:severity>SEVERITY_WARNING</tns:severity>
                </ns1:Message>
                <ns2:Value>
                   <ns2:AccountNumber>XXXXX</ns2:AccountNumber>
                   <ns2:CustomerAccountSite xmlns:ns7="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccountSite/"/>
                   <ns2:CustomerAccountSite xmlns:ns7="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccountSite/">
                      <ns2:CustomerAccountSiteUse xmlns:ns6="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccountSiteUse/">
                         <ns2:Location>XXXXXXXX</ns2:Location>
                         <ns2:Location>YYYYYYYY</ns2:Location>
                      </ns2:CustomerAccountSiteUse>
                   </ns2:CustomerAccountSite>
                   <ns2:CustomerAccountSite xmlns:ns7="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccountSite/"/>
                   <ns2:CustomerAccountSite xmlns:ns7="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccountSite/"/>
                </ns2:Value>
             </ns0:result>
          </ns0:findCustomerAccountResponse>
       </env:Body>
    </env:Envelope>  
      ');
    BEGIN
      SELECT EXTRACT(x, '//ns2:AccountNumber/text()', 'xmlns:ns2="http://xmlns.oracle.com/apps/cdm/foundation/parties/customerAccountService/"').getStringVal()
        INTO accountnumber FROM DUAL;
      dbms_output.put_line('accountnumber:'||accountnumber);
      
      SELECT EXTRACT(x, '//ns2:Location/text()', 'xmlns:ns2="http://xmlns.oracle.com/apps/cdm/foundation/parties/customerAccountService/"').getStringVal()
        INTO location FROM DUAL;
      dbms_output.put_line('locations:'||location);
      
      SELECT EXTRACT(x, '//ns2:Location[2]/text()', 'xmlns:ns2="http://xmlns.oracle.com/apps/cdm/foundation/parties/customerAccountService/"').getStringVal()
        INTO location FROM DUAL;
      dbms_output.put_line('location2:'||location);
      
      SELECT EXTRACT(x, '//ns2:Location[3]/text()', 'xmlns:ns2="http://xmlns.oracle.com/apps/cdm/foundation/parties/customerAccountService/"').getStringVal()
        INTO location FROM DUAL;
      dbms_output.put_line('location3:'||location);
    END;
    /
    

    这将输出

    accountnumber:XXXXX
    locations:XXXXXXXXYYYYYYYY
    location2:YYYYYYYY
    location3:
    

    【讨论】:

    • 这真的推进了我想做的事情,谢谢。
    • 很高兴听到,这就是这个网站的用途:-)
    猜你喜欢
    • 2014-11-14
    • 2020-10-04
    • 2019-12-20
    • 1970-01-01
    • 1970-01-01
    • 2011-08-05
    • 1970-01-01
    • 1970-01-01
    • 2011-06-24
    相关资源
    最近更新 更多