xml - 在 Oracle 9i 中解析 Web 服务响应

标签 xml oracle xpath web-services namespaces

我在解析来自 Web 服务的 XML 响应时遇到问题。我有一种感觉,这是由于命名空间问题造成的。但是,经过 4 个小时的研究、反复试验和绞尽脑汁,我还是没能解决这个问题。请帮忙。

我的目标是获取包含“ERRORS”节点的 dbms_xmldom.DOMNodeList。

XML 响应:

<?xml version="1.0" encoding="ISO-8859-1"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
    <GetMailDataResponse xmlns="https://www.customnamespacehost.com/webservicename">
        <GetMailDataResult>
            <Errors xmlns="">
                <ErrorDetail>Access Credentials Invalid</ErrorDetail>
            </Errors>
        </GetMailDataResult>
    </GetMailDataResponse>
</soap:Body>
</soap:Envelope>

代码:

不幸的是,这段代码可以编译但不起作用。

Error: "ORA-31013: Invalid XPATH expression.  

我相信这是由于 L_NS 变量中定义的多个命名空间造成的。我尝试设置 L_XPATH: /soap:Envelope/soap:Body 和 L_NS: xmlns:soap="http://schemas.xmlsoap.org/soap/envelope" 但是L_NL_RESULTS 最终为空。

-- Variable Declarations --

P_XML XMLTYPE;

L_CODE_NAME VARCHAR2(1000) := 'PKG_CIS_WS.FNC_STAGE_DATA';
L_XML_DOC                         dbms_xmldom.DOMDocument; 
L_NL_RESULTS                      dbms_xmldom.DOMNodeList;
L_NL_DONOR_SCREENING_RESULTS      dbms_xmldom.DOMNodeList;
L_N_RESULT                        dbms_xmldom.DOMNode;
L_XPATH                           VARCHAR2(4000);
L_NS                              VARCHAR2(4000);
L_TEMP                            VARCHAR2(4000);

-- Code Snippet --   

L_XML_DOC := dbms_xmldom.newDOMDocument(P_XML); 

L_XPATH :=  '/soap:Envelope/soap:Body/a:GetMailDataResponse/GetMailDataResult';
L_NS    :=  'xmlns:soap="http://schemas.xmlsoap.org/soap/envelope"' ||
            'xmlns:a="https://www.customnamespacehost.com/webservicename"';

L_NL_RESULTS := dbms_xslprocessor.selectNodes(
    dbms_xmldom.makeNode(L_XML_DOC)
  , L_XPATH
  , L_NS);

if not DBMS_XMLDOM.ISNULL(L_NL_RESULTS) then

  FOR RESULTS_REC IN 0 .. dbms_xmldom.getLength(L_NL_RESULTS) - 1 LOOP

    L_N_RESULT := dbms_xmldom.item(L_NL_RESULTS, RESULTS_REC);        
    L_TEMP := dbms_xmldom.GETNODENAME(L_N_RESULT);
    prc_bjm(L_CODE_NAME, 'L_TEMP = ' || L_TEMP, SQLCODE);
    dbms_xslprocessor.valueOf(L_N_RESULT, 'Errors/ErrorDetail/text()', L_TEMP);
    prc_bjm(L_CODE_NAME, 'L_TEMP = ' || L_TEMP, SQLCODE);

  END LOOP;

else

  prc_bjm(L_CODE_NAME, 'No nodes for: ' || L_XPATH || '(' || L_NS || ')', SQLCODE);

end if; -- if not DBMS_XMLDOM.ISNULL(L_NL_RESULTS)

最佳答案

嗯,看来我找到了答案。可能不是最好的答案,所以如果您知道更好(和/或更合适)的方法,请发表评论!

我的解决方案(同样,可能不是最好的解决方案)是真正搞乱 XPATH 查询。我添加了一些通配符和命名空间定义,事情就从那里开始。

工作代码

L_XML_DOC := dbms_xmldom.newDOMDocument(P_XML); 

L_XPATH :=  '/soap:Envelope/soap:Body/*[namespace-uri()="https://www.customnamespacehost.com/webservicename"]/*/*[namespace-uri()=""]/*';

L_NL_RESULTS := dbms_xslprocessor.selectNodes(
    dbms_xmldom.makeNode(L_XML_DOC)
  , L_XPATH);

dbms_xmldom.writetobuffer(L_XML_DOC, L_TEMP);
prc_bjm(L_CODE_NAME, 'L_TEMP = ' || L_TEMP, SQLCODE);

if not DBMS_XMLDOM.ISNULL(L_NL_RESULTS) then

  FOR RESULTS_REC IN 0 .. dbms_xmldom.getLength(L_NL_RESULTS) - 1 LOOP

    L_N_RESULT := dbms_xmldom.item(L_NL_RESULTS, RESULTS_REC); 

    L_TEMP := dbms_xmldom.GETNODENAME(L_N_RESULT);

    prc_bjm(L_CODE_NAME, 'L_TEMP = ' || L_TEMP, SQLCODE);

    dbms_xslprocessor.valueOf(L_N_RESULT, 'text()', L_TEMP);

    prc_bjm(L_CODE_NAME, 'L_TEMP = ' || L_TEMP, SQLCODE);

  END LOOP;

else

  prc_bjm(L_CODE_NAME, 'No nodes for: ' || L_XPATH || '(' || L_NS || ')', SQLCODE);

end if; -- if not DBMS_XMLDOM.ISNULL(L_NL_RESULTS)

此外,如果您知道这种方式为何有效,请发表评论。对我来说,命名空间(针对 GetMailDataResponse 节点)的定义没有别名(例如:“soap”)确实很奇怪。我想如果 GetMailDataResponse 节点定义如下,我原来的问题就会消失:

<a:GetMailDataResponse xmlns:a="https://www.customnamespacehost.com/webservicename">  

关于xml - 在 Oracle 9i 中解析 Web 服务响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2596445/

相关文章:

sql - 根据即将出现的行中存在的值更新行

macos - Selenium WebDriver - 无法在 Mac OS X 上的 Chrome 中关闭选择下拉菜单

java - 自定义 XPath 规则来检查 Java 中的 catch 子句

xml - 使用 SSIS 加载 XML 对 SQL 具有多个命名空间

java - ImageView ("headbar")不同的屏幕等

SQL根据其他行删除重复行

javascript - 用于按源顺序选择 *所有* 元素、文本节点和注释节点的 XPath 表达式

android - 管理多个按钮选择器?

java - 使用 2 个 Java 类显示 1 个 XML 文件的信息

sql - 在字段左侧添加零并连接 Oracle