2017-11-17 193 views
0

我想測試一個PL/SQL過程,它需要一個XML CLOB作爲一個參數PL/SQL - XML CLOB錯誤

PROCEDURE example_proc(ex_xml CLOB) IS 
BEGIN 

/* Find the second < (skip over declaration) */ 
ln_position := instr(pc_shipment_xml, '<', 1, 2); 
/* Find the space after the first tag */ 
ln_position := instr(pc_shipment_xml, ' ', ln_position, 1); 
/* Set the first part of the XML clob */ 
lc_shipment_xml := substr(pc_shipment_xml, 1, ln_position - 1); 
/* Skip the namespace */ 
ln_position  := instr(pc_shipment_xml, '>', ln_position, 1); 
lc_shipment_xml := lc_shipment_xml || substr(pc_shipment_xml, ln_position); 

/* Set the XML type */ 
lx_shipment_xml := xmltype(lc_shipment_xml); --RIGHT HERE IS WHERE IT ERRORS OUT 

這裏是我在想過去(因爲ex_xml CLOB的XML

ORA-19202: Error occurred in XML processing 
LPX-002255: end-element tag "ShipmentLines" does not match start-element tag "Shipment" 

請原諒我的無知,但這是我第一次寬:參數):在與最後一行

xml := 
'<Shipment> 
    <OrderNumber>00000</OrderNumber> 
    <ShipmentLines> 
    <ShipmentLine> 
     <OrderDetailId>000000</OrderDetailId> 
     <LineNumber>0</LineNumber> 
     <ItemId>00000</ItemId> 
     <UnitId>0000000</UnitId> 
     <BaseUom>X</BaseUom> 
     <Quantity1>000</Quantity1> 
    </ShipmentLine> 
    </ShipmentLines> 
</Shipment>'; 

,並出現了錯誤用PL/SQ處理XML,我是否缺少格式化的東西?據我所見,我正確打開和關閉我的標籤。任何輸入都是值得讚賞的。

+1

你真的嘗試用'instr','substr'等修改XML文檔嗎?看看[XML函數](https://docs.oracle.com/database/121/SQLRF/functions002.htm#SQLRF51185) –

回答

0

運行你的代碼

declare 
    pc_shipment_xml CLOB := '<Shipment> 
    <OrderNumber>00000</OrderNumber> 
    <ShipmentLines> 
    <ShipmentLine> 
     <OrderDetailId>000000</OrderDetailId> 
     <LineNumber>0</LineNumber> 
     <ItemId>00000</ItemId> 
     <UnitId>0000000</UnitId> 
     <BaseUom>X</BaseUom> 
     <Quantity1>000</Quantity1> 
    </ShipmentLine> 
    </ShipmentLines> 
</Shipment>'; 
    lc_shipment_xml varchar2(2000); 
    ln_position integer; 
BEGIN 
    /* Find the second < (skip over declaration) */ 
    ln_position := instr(pc_shipment_xml, '<', 1, 2); 
    /* Find the space after the first tag */ 
    ln_position := instr(pc_shipment_xml, ' ', ln_position, 1); 
    /* Set the first part of the XML clob */ 
    lc_shipment_xml := substr(pc_shipment_xml, 1, ln_position - 1); 
    /* Skip the namespace */ 
    ln_position  := instr(pc_shipment_xml, '>', ln_position, 1) + 1; 
    lc_shipment_xml := lc_shipment_xml || substr(pc_shipment_xml, ln_position); 
    dbms_output.put_line(lc_shipment_xml); 
end; 
/

給出了下面的輸出:

<Shipment> 
    <OrderNumber>00000</OrderNumber> 

    <ShipmentLine> 
     <OrderDetailId>000000</OrderDetailId> 
     <LineNumber>0</LineNumber> 
     <ItemId>00000</ItemId> 
     <UnitId>0000000</UnitId> 
     <BaseUom>X</BaseUom> 
     <Quantity1>000</Quantity1> 
    </ShipmentLine> 
    </ShipmentLines> 
</Shipment> 

,所以它看起來像你剝出開始ShipmentLines標記,但沒有結束標記

如果你知道要刪除的標籤的名稱可以更簡單地刪除與

lc_shipment_xml := regexp_replace(pc_shipment_xml, '</?ShipmentLines>'); 

或獲取由位置標籤:

l_tag := regexp_substr(pc_shipment_xml, '<(\w+)>',1,3,'i',1); 
lc_shipment_xml := regexp_replace(pc_shipment_xml, '</?' || l_tag || '>'); 

一個更好的辦法是使用xml funtions,這樣的事情:

declare 
    pc_shipment_xml CLOB := '<Shipment> 
    <OrderNumber>00000</OrderNumber> 
    <ShipmentLines> 
    <ShipmentLine> 
     <OrderDetailId>000000</OrderDetailId> 
     <LineNumber>0</LineNumber> 
     <ItemId>00000</ItemId> 
     <UnitId>0000000</UnitId> 
     <BaseUom>X</BaseUom> 
     <Quantity1>000</Quantity1> 
    </ShipmentLine> 
    </ShipmentLines> 
</Shipment>'; 
    lx_shipment_xml xmltype := xmltype(pc_shipment_xml); 
    lx_shipline_xml xmltype := xmltype(pc_shipment_xml); 
    lc_shipment_xml varchar2(2000); 
BEGIN 
    /* Set the XML type */ 
    select extract(lx_shipment_xml, '/Shipment/ShipmentLines/ShipmentLine') into lx_shipline_xml from dual; 
    select deletexml(lx_shipment_xml, '/Shipment/ShipmentLines') into lx_shipment_xml from dual; 
    select insertxmlafter(lx_shipment_xml, '/Shipment/OrderNumber', lx_shipline_xml) into lx_shipment_xml from dual; 
    select xmlserialize(content lx_shipment_xml) into lc_shipment_xml from dual; 
    dbms_output.put_line(lc_shipment_xml); 
end; 
/
0

,我是在解析XML的方式需要投入clob開頭的<?xml version="1.0"?>。解析方法不是我自己的代碼,所以改變我這樣做的方式不是一種選擇。謝謝