解析包含类似标记的XML的过程

时间:2016-05-04 10:31:40

标签: xml oracle xpath xmltype

我在表XML中存储了HOLDS_XML,其列类型为XML_TYPE

<?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;

但是在运行此程序时我收到错误

  

插入   选择e。*从Xmltable('/'传递:xml列streetname varchar2(50)路径'changeRequest / billOfMaterials / bomSiteItem / siteAddress / streetName')e   打开后    错误:Xml_Parser -19279 - ORA-19279:XPTY0004 - XQuery动态类型不匹配:预期的单例序列 - 得到多项序列

我想这是因为XML有多个streetname标签。读取所有值并将其插入某些变量的方法是什么。

1 个答案:

答案 0 :(得分: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;