2016-05-04 2 views
1

У меня есть XML хранится в таблице HOLDS_XML с колонного типа, как XML_TYPEПроцедура для разбора XML, содержащий аналогичных теги

<?xml version="1.0" encoding="UTF-8"?> 
<cus:request xsi:schemaLocation="http://www.bt.com/btgs/solutions/message/customerRequest C:\SalesSchema_Latest\RequestManagementV1.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sortarg="http://www.bt.com/btgs/solutions/library/SourceAndTarget" xmlns:siteType="http://www.bt.com/btgs/solutions/library/SiteType" xmlns:reqType="http://www.bt.com/btgs/solutions/library/RequestType" xmlns:prodType="http://www.bt.com/btgs/solutions/library/ProductType" xmlns:orgType="http://www.bt.com/btgs/solutions/library/OrganisationType" xmlns:ordType="http://www.bt.com/btgs/solutions/library/OrderType" xmlns:flexattType="http://www.bt.com/btgs/solutions/library/FlexattType" xmlns:contractType="http://www.bt.com/btgs/solutions/library/ContractType" xmlns:contactType="http://www.bt.com/btgs/solutions/library/ContractType" xmlns:addType="http://www.bt.com/btgs/solutions/library/AddressType" xmlns:cr="http://www.bt.com/btgs/solutions/message/customerRequest" xmlns:cus="http://www.bt.com/btgs/solutions/message/customerRequest" xmlns:prod="http://www.bt.com/btgs/solutions/library/ProductType"> 
    <sourceSystem name="Resign Tool" type="LQTWebsite"/> 
    <targetSystem name="MESSIA" type="Sales Tools"/> 
    <changeRequest customerRequestRef="" BTProjectManagementRef=""> 
    <billOfMaterials> 
     <bomSiteItem siteID="ID000009" siteInternalID="1163642" BTSiteType="host"> 
     <organisation> 
      <organisationRef>ID000003</organisationRef> 
     </organisation> 
     <siteContact> 
      <role/> 
      <firstName/> 
      <lastName/> 
      <telephone/> 
      <mobile/> 
      <fax/> 
      <email/> 
     </siteContact> 
     <siteName>BIRMINGHAM_001</siteName> 
     <siteReference>ID000009</siteReference> 
     <siteAddress> 
      <room/> 
      <floor/> 
      <building>BT BUILDING</building> 
      <streetNumber>5</streetNumber> 
      <streetName>BRINDLEY PLACE</streetName> 
      <locality>BIRMINGHAM</locality> 
      <city>BIRMINGHAM</city> 
      <county-state>WEST MIDLANDS</county-state> 
      <country ISOCountryCode="">UNITED KINGDOM</country> 
      <postcode>B1 2BL</postcode> 
     </siteAddress> 
     <coordinates gridSystem="easting-and-northing"> 
      <x-coordinate/> 
      <y-coordinate/> 
     </coordinates> 
     <installationLocation locID="ID000010"> 
      <subPremise>FLOOR 3 ROOM 6</subPremise> 
     </installationLocation>         
     </bomSiteItem> 
     <bomSiteItem siteID="ID000167" siteInternalID="1163644" BTSiteType="client"> 
     <organisation> 
      <organisationRef>ID000003</organisationRef> 
     </organisation> 
     <siteContact> 
      <role/> 
      <firstName/> 
      <lastName/> 
      <telephone/> 
      <mobile/> 
      <fax/> 
      <email/> 
     </siteContact> 
     <siteName>BIRMINGHAM_002</siteName> 
     <siteReference>ID000167</siteReference> 
     <siteAddress> 
      <room/> 
      <floor/> 
      <building>BT BUILDING</building> 
      <streetNumber>5</streetNumber> 
      <streetName>BRINDLEY PLACE</streetName> 
      <locality>BIRMINGHAM</locality> 
      <city>BIRMINGHAM</city> 
      <county-state>WEST MIDLANDS</county-state> 
      <country ISOCountryCode="">UNITED KINGDOM</country> 
      <postcode>B1 2BL</postcode> 
     </siteAddress> 
     <coordinates gridSystem="easting-and-northing"> 
      <x-coordinate/> 
      <y-coordinate/> 
     </coordinates> 
     <installationLocation locID="ID000168"> 
      <subPremise>FLOOR 3 ROOM 9</subPremise> 
     </installationLocation> 
     </bomSiteItem> 
     <bomSiteItem siteID="ID000208" siteInternalID="1163645" BTSiteType="client"> 
     <organisation> 
      <organisationRef>ID000003</organisationRef> 
     </organisation> 
     <siteContact> 
      <role/> 
      <firstName/> 
      <lastName/> 
      <telephone/> 
      <mobile/> 
      <fax/> 
      <email/> 
     </siteContact> 
     <siteName>BIRMINGHAM_003</siteName> 
     <siteReference>ID000208</siteReference> 
     <siteAddress> 
      <room/> 
      <floor/> 
      <building>BT BUILDING</building> 
      <streetNumber>5</streetNumber> 
      <streetName>BRINDLEY PLACE</streetName> 
      <locality>BIRMINGHAM</locality> 
      <city>BIRMINGHAM</city> 
      <county-state>WEST MIDLANDS</county-state> 
      <country ISOCountryCode="">UNITED KINGDOM</country> 
      <postcode>B1 2BL</postcode> 
     </siteAddress> 
     <coordinates gridSystem="easting-and-northing"> 
      <x-coordinate/> 
      <y-coordinate/> 
     </coordinates> 
     <installationLocation locID="ID000209"> 
      <subPremise>FLOOR 6 ROOM 9</subPremise> 
     </installationLocation> 
     </bomSiteItem> 
    </billOfMaterials> 

Я должен прочитать xpath хранится в таблице XML_MASTER, извлечь значения из XML и вставить его в другую таблицу. Структура таблицы, где Xpath хранится, как это

  XPATH             NODENAME  FIELDNAME 
changeRequest/billOfMaterials/bomSiteItem/siteAddress/streetName streetName  Site_Address_streetname 
changeRequest/billOfMaterials/bomSiteItem/siteContact/telephone  telephone  Site_Address_telephone 
changeRequest/billOfMaterials/bomSiteItem/siteContact/email   email   Site_Addres_email 
changeRequest/billOfMaterials/bomSiteItem/siteAddress/floor   floor   Site_Address_floor 
changeRequest/billOfMaterials/bomSiteItem/siteAddress/room   room   Site_Address_room 
changeRequest/billOfMaterials/bomSiteItem/siteAddress/county-state county-state Site_Address_country-state 
changeRequest/billOfMaterials/bomSiteItem/siteContact/mobile  mobile   Site_Address_mobile 
changeRequest/billOfMaterials/bomSiteItem/siteAddress/locality  locality  Site_Address_locality 
changeRequest/billOfMaterials/bomSiteItem/siteContact/firstName  firstName  Site_Address_firstName 
changeRequest/billOfMaterials/bomSiteItem/siteAddress/building  building  Site_Address_building 

Я создал процедуру следующим

create or replace 
PROCEDURE Xml_parser 
AS 
    TYPE cur_type IS ref CURSOR; 
    vxml   XMLTYPE; 
    Vvalue  Varchar2(100); 
    cur_string VARCHAR2(500); 
    vxpath  xml_master.xpath%TYPE; 
    Vnodename xml_Master.Nodename%Type; 
    VFieldName xml_master.fieldname%TYPE; 
    select_cur CUR_TYPE; 
    verror  VARCHAR2(500); 

    Cursor Cur_Xml_Master Is 
    select Xpath, Nodename, fieldname 
    from xml_master ; 


BEGIN 
    SELECT xml_col 
    INTO vxml 
    FROM holds_xml; 

    dbms_output.Put_line ('inserted'); 

    OPEN cur_xml_master; 

    Loop 
     FETCH cur_xml_master INTO vxpath, vnodename, vfieldname; 

     Exit When Cur_Xml_Master%Notfound ; 

     Cur_String := 'Select e."' 
         ||Vnodename|| 
         '" From Xmltable(''/'' ' 
         || 'Passing :xml columns "' 
         ||Vnodename|| 
         '" varchar2(200) path ''' 
         ||Vxpath|| 
         ''')e'; 

      dbms_output.Put_line (Cur_String);   


      OPEN select_cur FOR cur_string USING vxml; 
      dbms_output.Put_line ('after open'); 

       LOOP 
        FETCH select_cur INTO vvalue; 

        EXIT WHEN select_cur%NOTFOUND; 

        dbms_output.Put_line (Cur_String);   
        dbms_output.Put_line ('value is: '|| vvalue); 

       END LOOP; 



CLOSE select_cur; 
END LOOP; 

CLOSE cur_xml_master; 

END; 

Но во время выполнения этой процедуры я получаю ошибку

inserted Select e.* From Xmltable('/' Passing :xml columns streetname varchar2(50) path 'changeRequest/billOfMaterials/bomSiteItem/siteAddress/streetName')e after open error: Xml_Parser -19279 - ORA-19279: XPTY0004 - XQuery dynamic type mismatch: expected singleton sequence - got multi-item sequence

Я полагаю, что это потому что XML имеет несколько тегов streetname. Каким образом можно считывать все значения и вставлять их в некоторые переменные.

+0

@ J.Chomel Я не понял, что вы сказали? Откуда вы хотите, чтобы я получил улицу? – Vishal5364

+0

У меня сейчас нет XSD. На самом деле это довольно старый db в доступе MS, который я конвертирую в Oracle. У меня нет никакого XSD относительно XML – Vishal5364

+0

Я просто пытаюсь угадать из-за ошибки ... Можете ли вы загрузить файл, когда это только одна запись? (удалите другие '' billOfMaterials'' записи, оставив только один на вашем входе). –

ответ

1

1) Вам здесь не нужно использовать динамический запрос.

2) Поместите свой xpath (// + ваш xpath) после xmltable и определите столбец по умолчанию в инструкции xmltable.

declare 
v_xml xmltype := xmltype('<rowset> 
               <row> 
               <x>1</x> 
               <y>lalal</y> 
               </row> 
               <row> 
               <x>2</x> 
               <y>y1</y> 
               </row> 
               </rowset>'); 
xpath varchar2(20) := '//rowset/row/x';            
begin 
for rec in (select abc from xmltable(xpath passing v_xml columns abc varchar2(200) path '.')) loop 
    dbms_output.put_line(rec.abc); 
end loop; 
end; 
Смежные вопросы