Oracle DB parsing XML instance operation summary

       When Oracle PLSQL calls third-party SOAP Web Services, Oracle needs to have some built-in XML parsing functions, which can easily parse the XML content returned by SOAP Web Services. The following describes common XML built-in functions and usage methods:

  1. EXTRACT(XMLType_instance,XPath_string,[namespace_string]) Usage
    This function is used to obtain a node or a node set in XML
    1.1 Get the content of the Cities node
    SELECT Extract(Xmltype('<?xml version="1.0" encoding="utf-8"?>
    <Root>
      <Cities> 
        <City><Id>1</Id><CityName>北京市</CityName><ZipCode>100000</ZipCode></City>  
        <City><Id>2</Id><CityName>天津市</CityName><ZipCode>100001</ZipCode></City>
        <City><Id>3</Id><CityName>石家庄市</CityName><ZipCode>050000</ZipCode></City>  
        <City><Id>4</Id><CityName>唐山市</CityName><ZipCode>063000</ZipCode></City>  
        <City><Id>5</Id> <CityName>秦皇岛市</CityName><ZipCode>066000</ZipCode></City>  
        <City><Id>6</Id><CityName>邯郸市</CityName><ZipCode>056000</ZipCode></City> 
      </Cities>
    </Root>')
                   ,'/Root/Cities')
      FROM Dual;
    1.2 Get the content of the node with a named space
    SELECT Extract(Xmltype('<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
      <soap:Body>
        <MFCRequest>
          <Cities> 
            <City><Id>1</Id><CityName>北京市</CityName><ZipCode>100000</ZipCode></City>  
            <City><Id>2</Id><CityName>天津市</CityName><ZipCode>100001</ZipCode></City>
            <City><Id>3</Id><CityName>石家庄市</CityName><ZipCode>050000</ZipCode></City>  
            <City><Id>4</Id><CityName>唐山市</CityName><ZipCode>063000</ZipCode></City>  
            <City><Id>5</Id> <CityName>秦皇岛市</CityName><ZipCode>066000</ZipCode></City>  
            <City><Id>6</Id><CityName>邯郸市</CityName><ZipCode>056000</ZipCode></City> 
          </Cities>
        </MFCRequest>
      </soap:Body>
    </soap:Envelope>'),'/soap:Envelope/soap:Body/MFCRequest','xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"')
    from dual;
    <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">其中xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 为命名空间。

    参考官方API:https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions051.htm
     
  2. EXTRACTVALUE(XMLType_instance,XPath_string,[namespace_string]) Usage
    This function is used to return the data of a specific XML node path
    2.1 Get the value of an element
    SELECT Extractvalue(Xmltype('<?xml version="1.0" encoding="utf-8"?>
    <Root> 
      <Cities> 
        <City> 
          <Id>1</Id><CityName>北京市</CityName><ZipCode>100000</ZipCode> 
        </City>  
      </Cities> 
    </Root>')
                        ,'/Root/Cities/City/CityName')
      FROM Dual;

    2.2 Get the value of an element in a namespaced XML
    SELECT Extractvalue(Xmltype('<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
       <soap:Body>
          <MFCRequestResponse>
             <MFCRequestResult>
                <IsSuccessed>false</IsSuccessed>
                <Message>用户验证失败</Message>
             </MFCRequestResult>
          </MFCRequestResponse>
       </soap:Body>
    </soap:Envelope>')
                        ,'/soap:Envelope/soap:Body/MFCRequestResponse/MFCRequestResult/IsSuccessed'
                        ,'xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"')
      FROM Dual;

    Note: EXTRACTVALUE can only parse the value of a single XML leaf node. Cannot parse the content of the root node and child nodes, or the values ​​of multiple identical XML leaf nodes.
    Refer to the official API: https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions052.htm#i1131042
  3.  Table conversion XML
    3.1 DBMS_XMLGEN.GETXML ​​Table conversion XML
    SELECT Dbms_Xmlgen.Getxml('SELECT Msi.Segment1 Item_Num
    ,Msi.Description Item_Desc
    ,Msi.Primary_Unit_Of_Measure UOM
    FROM Mtl_System_Items_b Msi
    WHERE Msi.Organization_Id = 82
    AND Rownum <= 30')
      FROM Dual;
    Results:

    1. The default root element is <ROWSET> and the node element of each row is <ROW>
    2. The column name or column alias is the element of each value.
    Refer to the official API: https://docs.oracle.com/cd/B19306_01 /appdev.102/b14258/d_xmlgen.htm#i1012053

    3.2 Combination of XMLELEMENT, XMLFOREST and XMLAGG The
        XMLAGG  function is used to summarize all XML documents and generate an XML document.
    SELECT XMLELEMENT("ITEMS"
                      ,Xmlagg(Xmlelement("ITEM"
                                        ,XMLFOREST(Msi.Segment1 Item_Number
                                                 ,Msi.Description Item_Desc))))
      FROM Mtl_System_Items_b Msi
     WHERE Msi.Organization_Id = 82
       AND Rownum <= 10;

    Refer to the official API: https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions215.htm
    3.3 Examples of two-level or multi-level XML structure, such as BOM list:
    SELECT Xmlelement("BOMS" --第一层
                      ,Xmlagg(Xmlelement("BOM" --第二层
                                        ,Xmlforest(Bbm.Bill_Sequence_Id
                                                 ,Bbm.Organization_Id
                                                 ,Bbm.Assembly_Item_Id
                                                 ,Msi.Segment1 Assembly_Item
                                                 ,Msi.Description Assembly_Desc)
                                        ----Componentes Start---------------------         
                                        ,(SELECT Xmlelement("COMPONENTS"
                                                          ,Xmlagg(Xmlelement("COMPONENT"
                                                                            ,Xmlforest(Bic.Component_Sequence_Id
                                                                                     ,Bic.Component_Item_Id
                                                                                     ,Msi.Segment1
                                                                                      Component_Item
                                                                                     ,Msi.Description
                                                                                      Component_Desc)))) AS Components
                                          FROM Bom_Inventory_Components Bic
                                              ,Mtl_System_Items_b       Msi
                                         WHERE Bic.Component_Item_Id =
                                               Msi.Inventory_Item_Id
                                           AND Bic.Effectivity_Date <= SYSDATE
                                           AND Nvl(Bic.Disable_Date, SYSDATE) >=
                                               Trunc(SYSDATE)
                                           AND Bic.Bill_Sequence_Id =
                                               Bbm.Bill_Sequence_Id
                                           AND Msi.Organization_Id =
                                               Bbm.Organization_Id)
                                        ----Componentes End---------------------         
                                        )))
      FROM Bom_Bill_Of_Materials Bbm
          ,Mtl_System_Items_b    Msi
     WHERE Bbm.Assembly_Item_Id = Msi.Inventory_Item_Id
       AND Bbm.Organization_Id = Msi.Organization_Id
       AND Bbm.Bill_Sequence_Id IN
           (SELECT DISTINCT Bic.Bill_Sequence_Id
              FROM Bom_Inventory_Components Bic
             WHERE Bic.Effectivity_Date <= SYSDATE
               AND Nvl(Bic.Disable_Date, SYSDATE) >= Trunc(SYSDATE)
               AND Rownum < 2);
    The output is as follows:
    <BOMS>
      <BOM>
        <BILL_SEQUENCE_ID>1</BILL_SEQUENCE_ID>
        <ORGANIZATION_ID>83</ORGANIZATION_ID>
        <ASSEMBLY_ITEM_ID>3</ASSEMBLY_ITEM_ID>
        <ASSEMBLY_ITEM>1110010001</ASSEMBLY_ITEM>
        <ASSEMBLY_DESC>子装配件</ASSEMBLY_DESC>
        <COMPONENTS>
          <COMPONENT>
            <COMPONENT_SEQUENCE_ID>2</COMPONENT_SEQUENCE_ID>
            <COMPONENT_ITEM_ID>1</COMPONENT_ITEM_ID>
            <COMPONENT_ITEM>WD01</COMPONENT_ITEM>
            <COMPONENT_DESC>家用电器</COMPONENT_DESC>
          </COMPONENT>
          <COMPONENT>
            <COMPONENT_SEQUENCE_ID>3</COMPONENT_SEQUENCE_ID>
            <COMPONENT_ITEM_ID>2</COMPONENT_ITEM_ID>
            <COMPONENT_ITEM>WD02</COMPONENT_ITEM>
            <COMPONENT_DESC>家用电扇</COMPONENT_DESC>
          </COMPONENT>
        </COMPONENTS>
      </BOM>
    </BOMS>
  4. XMLTABLE([XML_namespace],XQuery_string,XMLTABLE_options) ( XML conversion table usage)
    4.1 XML conversion table
    SELECT *
      FROM Xmltable('/Cities/City' Passing Xmltype('<?xml version="1.0" encoding="utf-8"?>
    <Cities> 
      <City><Id>1</Id><CityName>北京市</CityName><ZipCode>100000</ZipCode></City>  
      <City><Id>2</Id><CityName>天津市</CityName><ZipCode>100001</ZipCode></City>
      <City><Id>3</Id><CityName>石家庄市</CityName><ZipCode>050000</ZipCode></City>  
      <City><Id>4</Id><CityName>唐山市</CityName><ZipCode>063000</ZipCode></City>  
      <City><Id>5</Id> <CityName>秦皇岛市</CityName><ZipCode>066000</ZipCode></City>  
      <City><Id>6</Id><CityName>邯郸市</CityName><ZipCode>056000</ZipCode></City>  
    </Cities>') Columns City_Id NUMBER Path '/City/Id'
                    ,City_Name VARCHAR2(240) Path '/City/CityName'
                    ,Zip_Code VARCHAR2(10) Path '/City/ZipCode')

    4.2 XML to watchband namespace
    SELECT *
      FROM XMLTABLE(XMLNAMESPACES('http://schemas.xmlsoap.org/soap/envelope/' AS
                                  "soapenv1",
                                  'http://platform.nucleusconnect.com/wsdl/EUCServices' AS
                                  "euc1"),
                    '$B/soapenv1:Envelope/soapenv1:Body/euc1:EUCRevisionNewOrderRequest/body'
                    PASSING
                    (select xmltype('<?xml version="1.0" encoding="utf-8"?>
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:euc="http://platform.nucleusconnect.com/wsdl/EUCServices">
      <soapenv:Body>
        <euc:EUCRevisionNewOrderRequest>
          <header>
            <Department>Business Solution - Business Broadband</Department>
            <AcceptTNC>Yes</AcceptTNC>
            <TransactionId>FB000120170119181518436</TransactionId>
          </header>
          <body>
            <SalesOrderId>2017011914381897</SalesOrderId>
          </body>
          <body>
            <SalesOrderId>2017011914381897</SalesOrderId>
          </body>
        </euc:EUCRevisionNewOrderRequest>
      </soapenv:Body>
    </soapenv:Envelope>')
                       from dual a ) AS B COLUMNS SalesOrderId
                    VARCHAR2(128) PATH '/body/SalesOrderId')

    Refer to the official API: https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions228.htm
  5. EXISTSNODE(XMLType_instance, XPath_string, namespace_string) Usage
    This function is used to determine whether the path of a specific XML node exists, returning 0 means the node does not exist, and returning 1 means the node exists.
    As follows: Determine whether the value of Id element 2 under /Cities/City in XML exists
    WITH Xmlcities AS
     (SELECT Xmltype('<?xml version="1.0" encoding="utf-8"?>
    <Cities> 
      <City><Id>1</Id><CityName>北京市</CityName><ZipCode>100000</ZipCode></City>  
      <City><Id>2</Id><CityName>天津市</CityName><ZipCode>100001</ZipCode></City>
      <City><Id>3</Id><CityName>石家庄市</CityName><ZipCode>050000</ZipCode></City>  
      <City><Id>4</Id><CityName>唐山市</CityName><ZipCode>063000</ZipCode></City>  
      <City><Id>5</Id> <CityName>秦皇岛市</CityName><ZipCode>066000</ZipCode></City>  
      <City><Id>6</Id><CityName>邯郸市</CityName><ZipCode>056000</ZipCode></City>  
    </Cities>') AS Xml_Object
        FROM Dual)
    SELECT *
      FROM Xmlcities T1
     WHERE Existsnode(Xml_Object, '/Cities/City[Id="2"]') = 1
  6. Untable XML parsing example script
    DECLARE
      --创建XML解析器实例XMLPARSER.parser
      Xmlpar Xmlparser.Parser := Xmlparser.Newparser;
      --定义DOM文档对象
      Xmldoc Xmldom.Domdocument;
      --定义解析XML所需要的其他对象
      Lo_City_Nodelist Xmldom.Domnodelist; --City节点集
      Lo_City_Node     Xmldom.Domnode; --City节点
      Ln_City_Count    NUMBER;
      Chilnodes        Xmldom.Domnodelist; --City节点下元素
      Ln_City_Id       NUMBER;
      Lv_City_Name     VARCHAR2(240);
      Lv_Zip_Code      VARCHAR2(10);
      Xmlclobdata      CLOB := '<?xml version="1.0" encoding="utf-8"?>
    <Cities> 
      <City><Id>1</Id><CityName>北京市</CityName><ZipCode>100000</ZipCode></City>  
      <City><Id>2</Id><CityName>天津市</CityName><ZipCode>100001</ZipCode></City>
      <City><Id>3</Id><CityName>石家庄市</CityName><ZipCode>050000</ZipCode></City>  
      <City><Id>4</Id><CityName>唐山市</CityName><ZipCode>063000</ZipCode></City>  
      <City><Id>5</Id> <CityName>秦皇岛市</CityName><ZipCode>066000</ZipCode></City>  
      <City><Id>6</Id><CityName>邯郸市</CityName><ZipCode>056000</ZipCode></City> 
    </Cities>';
    BEGIN
      --创建XML解析对象
      Xmlpar := Xmlparser.Newparser;
      BEGIN
        --解析文档并创建一个新的DOM文档。
        Xmlparser.Parseclob(Xmlpar, Xmlclobdata);
      EXCEPTION
        WHEN OTHERS THEN
          Dbms_Output.Put_Line('Xml文件格式错误或者不完整');
          RETURN;
      END;
      --获得XML文档
      Xmldoc := Xmlparser.Getdocument(Xmlpar);
      --释放解析器实例
      Xmlparser.Freeparser(Xmlpar);
      --获取所有City节点
      Lo_City_Nodelist := Xmldom.Getelementsbytagname(Xmldoc, 'City');
      --获得City节点个数
      Ln_City_Count := Xmldom.Getlength(Lo_City_Nodelist);
      Dbms_Output.Put_Line('Ln_City_Count:' || Ln_City_Count);
      --遍历City节点
      FOR i IN 0 .. Ln_City_Count - 1 LOOP
        --获得City节点
        Lo_City_Node := Xmldom.Item(Lo_City_Nodelist, i);
        Chilnodes    := Xmldom.Getchildnodes(Lo_City_Node);
        --获取City节点元素
        Ln_City_Id   := Xmldom.Getnodevalue(Xmldom.Getfirstchild(Xmldom.Item(Chilnodes
                                                                            ,0)));
        Lv_City_Name := Xmldom.Getnodevalue(Xmldom.Getfirstchild(Xmldom.Item(Chilnodes
                                                                            ,1)));
        Lv_Zip_Code  := Xmldom.Getnodevalue(Xmldom.Getfirstchild(Xmldom.Item(Chilnodes
                                                                            ,2)));
        Dbms_Output.Put('Ln_City_Id:' || Ln_City_Id);
        Dbms_Output.Put(',Lv_City_Name:' || Lv_City_Name);
        Dbms_Output.Put(',Lv_Zip_Code:' || Lv_Zip_Code);
        Dbms_Output.Put_Line('');
      END LOOP;
      --释放文档对象
      Xmldom.Freedocument(Xmldoc);
      --异常与错误处理
    EXCEPTION
      WHEN OTHERS THEN
        Dbms_Output.Put_Line(SQLERRM);
    END;


     

Guess you like

Origin blog.csdn.net/chenxianping/article/details/102899492