【问题标题】:I'm trying to parse an XML in PL/SQL. I am unable to retrieve the attribute values from a tag, what am i doing wrong?我正在尝试在 PL/SQL 中解析 XML。我无法从标签中检索属性值,我做错了什么?
【发布时间】:2019-10-15 06:53:44
【问题描述】:

以下 XML 将无法解析。请找到我正在使用的确切代码 -

DECLARE
  x XMLType := XMLType(
    '<ns0:CreateSODSOrder xmlns:ns0="http://schemas.dell.com/services/isp/OrderHistory/3.5" xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" MessageType="CREATE">
  <ns0:CreateOrder>
    <ns0:SalesOrder ORDER_NUM="302199286" DPID="GB2003-2120-85049" PO_NUM="test" ORDER_BUID="202" DPS_NUM="" CHANNEL="ENTP" SUB_CHANNEL="GB_IC1A" ORDER_TYPE="GB ENT Order" REBOOKED_ORDER_NUM="" SALES_REP_NAME="SANJANA_D_C" ORIGINAL_ORDER_REF_NUM="" AMF_ORDER_NUM="" IR_NUM="GB2003-2120-85049" CCN="GB_IC1A" CUSTOMER_NUM="GB90117414" CUSTOMER_BUID="202" ORDER_DATE="2019-09-30T07:59:32" COUNTRY_NUM="GB" CCN_DESC="GB Indirect Certified  Tier 1A"/>
  </ns0:CreateOrder>
</ns0:CreateSODSOrder>');
BEGIN
  FOR r IN (
    SELECT ExtractValue(column_value,'Sales/@ORDER_NAME') as name
         -- ,ExtractValue(Value(p),'/row/Address/State/text()') as state
          --,ExtractValue(Value(p),'/row/Address/City/text()') as city
    FROM   TABLE(XMLSequence(Extract(x,'/CreateSODSOrder/CreateOrder/SalesOrder')))
    ) LOOP
          dbms_output.put_line(r.name);
  END LOOP;
    dbms_output.put_line('out');
END;

当我将 ns0: 与 CreateSODSOrder/CreateOrder/SalesOrder 一起使用时,它会引发 XML 解析错误。

【问题讨论】:

    标签: plsql xml-parsing xmlhttprequest plsqldeveloper


    【解决方案1】:

    您收到 XML 解析错误,因为缺少命名空间定义。 以下代码将解决命名空间问题,但在不知道您的意图的情况下很难获取值

    DECLARE
      x XMLType := XMLType(
        '<ns0:CreateSODSOrder xmlns:ns0="http://schemas.dell.com/services/isp/OrderHistory/3.5" xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" MessageType="CREATE">
      <ns0:CreateOrder>
        <ns0:SalesOrder ORDER_NUM="302199286" DPID="GB2003-2120-85049" PO_NUM="test" ORDER_BUID="202" DPS_NUM="" CHANNEL="ENTP" SUB_CHANNEL="GB_IC1A" ORDER_TYPE="GB ENT Order" REBOOKED_ORDER_NUM="" SALES_REP_NAME="SANJANA_D_C" ORIGINAL_ORDER_REF_NUM="" AMF_ORDER_NUM="" IR_NUM="GB2003-2120-85049" CCN="GB_IC1A" CUSTOMER_NUM="GB90117414" CUSTOMER_BUID="202" ORDER_DATE="2019-09-30T07:59:32" COUNTRY_NUM="GB" CCN_DESC="GB Indirect Certified  Tier 1A"/>
      </ns0:CreateOrder>
    </ns0:CreateSODSOrder>');
    BEGIN
      FOR r IN (
        SELECT ExtractValue(column_value,'Sales/@ORDER_NAME') as name
             -- ,ExtractValue(Value(p),'/row/Address/State/text()') as state
              --,ExtractValue(Value(p),'/row/Address/City/text()') as city
        FROM   TABLE(XMLSequence(Extract(x,'/ns0:CreateSODSOrder/ns0:CreateOrder/ns0:SalesOrder', 'xmlns:ns0="http://schemas.dell.com/services/isp/OrderHistory/3.5"' )))
        ) LOOP
              dbms_output.put_line(r.name);
      END LOOP;
        dbms_output.put_line('out');
    END;
    

    使用XMLTABLE 是个好主意,因为ExtractValue 有点过时且不推荐使用。

    下面添加了获取XMLTABLE属性的示例代码。

    DECLARE
    CURSOR get_data IS
    SELECT * 
    FROM XMLTABLE(xmlnamespaces('http://schemas.dell.com/services/isp/OrderHistory/3.5' as "ns0", 'http://schemas.xmlsoap.org/soap/envelope/' as "soap-env" ),'ns0:CreateSODSOrder/ns0:CreateOrder/ns0:SalesOrder'
       passing xmltype('<ns0:CreateSODSOrder xmlns:ns0="http://schemas.dell.com/services/isp/OrderHistory/3.5" xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" MessageType="CREATE">
      <ns0:CreateOrder>
        <ns0:SalesOrder ORDER_NUM="302199286" DPID="GB2003-2120-85049" PO_NUM="test" ORDER_BUID="202" DPS_NUM="" CHANNEL="ENTP" SUB_CHANNEL="GB_IC1A" ORDER_TYPE="GB ENT Order" REBOOKED_ORDER_NUM="" SALES_REP_NAME="SANJANA_D_C" ORIGINAL_ORDER_REF_NUM="" AMF_ORDER_NUM="" IR_NUM="GB2003-2120-85049" CCN="GB_IC1A" CUSTOMER_NUM="GB90117414" CUSTOMER_BUID="202" ORDER_DATE="2019-09-30T07:59:32" COUNTRY_NUM="GB" CCN_DESC="GB Indirect Certified  Tier 1A"/>
      </ns0:CreateOrder>
    </ns0:CreateSODSOrder>')
               COLUMNS 
               ORDER_NUM      VARCHAR2(30)    PATH '@ORDER_NUM',
               DPID           VARCHAR2(30)    PATH '@DPID');
    BEGIN  
    FOR rec_ IN get_data LOOP
      dbms_output.put_line(rec_.ORDER_NUM);
      dbms_output.put_line(rec_.DPID);
      END LOOP;
    END;
    

    【讨论】:

      猜你喜欢
      • 2023-04-04
      • 1970-01-01
      • 1970-01-01
      • 2021-04-22
      • 1970-01-01
      • 1970-01-01
      • 2018-06-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多