1

我在 Oracle 11g 中有一个函数,它使用 UTL_HTTP 来使用 Web 服务。我将 SOAP 响应存储在 CLOB 中。

经过几个小时的研究,我仍然没有找到直接解析 clob 中的 XML 字段的方法。

Clob 中的 SOAP 响应如下所示:

(CLOB) <?xml version="1.0" ?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <GET_PERMITOutput xmlns="http://xmlns.oracle.com/orawsv/DBUSER/MYSERV">
      <RETURN>
        <STATUS_CODES>
          <stat>REC</stat>
        </STATUS_CODES>
      </RETURN>
    </GET_PERMITOutput>
  </soap:Body>
</soap:Envelope>

我希望能够解析出该值“REC”(在其他情况下会有多个状态代码)并在我的函数中对其进行处理。

4

2 回答 2

2

首先,将 XML 存储在XMLType列中可能会更容易。否则,为了解析数据,您必须在运行时将 转换CLOB为。XMLType

但是,假设您从 a 开始CLOB,您应该能够执行类似的操作

select xmltype( xml_response ).extract('//stat/text()',
                                       'xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" ' ||
                                       'xmlns="http://xmlns.oracle.com/orawsv/DBUSER/MYSERV').getStringVal()
 from foo

提取数据。对于我的测试,我创建了一个表CLOB

SQL> create table foo(
  2    xml_response clob
  3  );

Table created.

插入您的示例数据

SQL> insert into foo values( '<?xml version="1.0" ?>
  2  <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  3    <soap:Body>
  4      <GET_PERMITOutput xmlns="http://xmlns.oracle.com/orawsv/DBUSER/MYSERV">
  5        <RETURN>
  6          <STATUS_CODES>
  7            <stat>REC</stat>
  8          </STATUS_CODES>
  9        </RETURN>
 10      </GET_PERMITOutput>
 11    </soap:Body>
 12  </soap:Envelope>');

1 row created.

然后编写查询来提取它

SQL> ed
Wrote file afiedt.buf

  1  select xmltype( xml_response ).extract('//stat/text()',
  2                                         'xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" ' ||
  3                                         'xmlns="http://xmlns.oracle.com/orawsv/DBUSER/MYSERV').getStringVal()
  4*  from foo
SQL> /

XMLTYPE(XML_RESPONSE).EXTRACT('//STAT/TEXT()','XMLNS:SOAP="HTTP://SCHEMAS.XMLSOA
--------------------------------------------------------------------------------
REC
于 2012-06-28T20:28:32.763 回答
0

我找到了一种无需插入临时表即可执行此操作的方法。我的函数以 CLOB 的形式获取 SOAP 响应,并将其存储在一个名为“resp”的变量中,该变量在下面使用,无需将 clob 插入任何临时对象:

with t as (select xmltype(resp) xcol from dual)
  select status
  into tmp FROM t, XDBUSER.XDBUSER_XML
     , XMLTABLE( XMLNAMESPACES ('http://schemas.xmlsoap.org/soap/envelope/' as "soap", 'http://xmlns.oracle.com/orawsv/DBUSER/MYSERV' as "a")
        ,'/soap:Envelope/soap:Body/a:GET_PERMITOutput/a:RETURN/a:STATUS_CODES'
              PASSING XMLTYPE.CreateXML(XML_CLOB)
              COLUMNS "STATUS"  VARCHAR2(500) PATH 'a:stat');

与 XMLType 相比,clob 是处理soap 请求的更安全的方法,因为返回的数据可能超过 32767 字节。

于 2012-06-29T15:42:51.980 回答