2017-11-17 188 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"?>。解析方法不是我自己的代码,所以改变我这样做的方式不是一种选择。谢谢