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:
- 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
1.2 Get the content of the node with a named spaceSELECT 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;
<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/" 为命名空间。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;
参考官方API:https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions051.htm
- 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 elementSELECT 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 XMLSELECT 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 - Table conversion XML
3.1 DBMS_XMLGEN.GETXML Table conversion XML
Results: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;
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:
The output is as follows: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);
<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>
- XMLTABLE([XML_namespace],XQuery_string,XMLTABLE_options) ( XML conversion table usage)
4.1 XML conversion tableSELECT * 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 namespaceSELECT * 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 - 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 existsWITH 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
- 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;