在PL/SQL中利用XML ,Oracle提供了几个组件,让开发人员能轻松地利用XML技术。这些组件包括:
- XML分析程序。即用来分析、构造和验证XML文档。
- XPath引擎。它是使用Xpath(XML标准的另一个元素)说明语法在内存中搜索XML文档的实用程序。SLT处理器。它在Oracle数据库中支持XSLT,允许您把XML文档转换成其他格式。
- XML SQL实用程序。可以使用SQL产生XML文档,使您可以在Oracle数据库表格中轻松地插入基于XML的数据。
对于PL/SQL开发人员而言,XML分析程序是最重要的组件。通过它,您可以在Oracle数据库中分析、操纵和转换XML文档。XML分析程序由一套APIs(应用程序编程接口)构成。
XML generator
示例Test.xml,内容如下:
<staff content = "name and id">
<member>
<name>Arwen</name>
<eno>123</eno>
</member>
<member>
<name>Tom</name>
<eno>456</eno>
</member>
</staff>
declare
doc XMLDOM.DOMDOCUMENT;
doc_node XMLDOM.DOMNODE;
root_node XMLDOM.DOMNODE;
user_node XMLDOM.DOMNODE;
item_node XMLDOM.DOMNODE;
root_elmt XMLDOM.DOMELEMENT;
user_elmt XMLDOM.DOMELEMENT;
item_elmt XMLDOM.DOMELEMENT;
item_text XMLDOM.DOMTEXT;
begin
doc := XMLDOM.NEWDOMDOCUMENT;
xmldom.setVersion(doc, '1.0');
xmldom.setCharset(doc, 'UTF-8');
--根节点
doc_node := XMLDOM.MAKENODE(doc);
root_elmt := XMLDOM.CREATEELEMENT(doc,'staff');
XMLDOM.SETATTRIBUTE(root_elmt,'content ','name and id');
root_node:=XMLDOM.APPENDCHILD(doc_node, XMLDOM.MAKENODE(root_elmt));
--节点1
user_elmt := XMLDOM.CREATEELEMENT(doc,'member');
user_node :=XMLDOM.APPENDCHILD(root_node, XMLDOM.MAKENODE(user_elmt));
item_elmt :=XMLDOM.CREATEELEMENT(doc,'name');
item_node :=XMLDOM.APPENDCHILD(user_node, XMLDOM.MAKENODE(item_elmt));
item_text := XMLDOM.CREATETEXTNODE(doc,'Arwen');
item_node:=XMLDOM.APPENDCHILD(item_node, XMLDOM.MAKENODE(item_text));
item_elmt :=XMLDOM.CREATEELEMENT(doc,'eno');
item_node :=XMLDOM.APPENDCHILD(user_node, XMLDOM.MAKENODE(item_elmt));
item_text := XMLDOM.CREATETEXTNODE(doc,'123');
item_node:=XMLDOM.APPENDCHILD(item_node, XMLDOM.MAKENODE(item_text));
--节点2
user_elmt := XMLDOM.CREATEELEMENT(doc,'member');
user_node :=XMLDOM.APPENDCHILD(root_node, XMLDOM.MAKENODE(user_elmt));
item_elmt :=XMLDOM.CREATEELEMENT(doc,'name');
item_node :=XMLDOM.APPENDCHILD(user_node, XMLDOM.MAKENODE(item_elmt));
item_text := XMLDOM.CREATETEXTNODE(doc,'tom');
item_node:=XMLDOM.APPENDCHILD(item_node, XMLDOM.MAKENODE(item_text));
item_elmt :=XMLDOM.CREATEELEMENT(doc,'eno');
item_node :=XMLDOM.APPENDCHILD(user_node, XMLDOM.MAKENODE(item_elmt));
item_text := XMLDOM.CREATETEXTNODE(doc,'456');
item_node:=XMLDOM.APPENDCHILD(item_node, XMLDOM.MAKENODE(item_text));
--写入操作系统文件中
XMLDOM.WRITETOFILE(doc,'DIR'||'\Test.xml');--注意必须先创建一个文件目录dir
--可以通过语句 : create or replace directory dir as 'd:\temp'
XMLDOM.FREEDOCUMENT(doc);
end;
XML parser
示例Test.xml,内容如下:
<staff content = "name and id">
<member>
<name>Arwen</name>
<eno>123</eno>
</member>
<member>
<name>Tom</name>
<eno>456</eno>
</member>
</staff>
xml decode
decode_list_enterprise_request(xmldom.item (xmldom.getElementsByTagName (req_domdoc ,'staff'), 0));
FUNCTION decode_staff (p_node IN DBMS_XMLDOM.DOMNode ) RETURN
staff IS
l_obj staff ;
l_children DBMS_XMLDOM.DOMNodeList ;
l_length INTEGER ;
l_i INTEGER ;
l_child DBMS_XMLDOM.DOMNode ;
l_name VARCHAR2 (32767);
BEGIN
l_obj := staff();
l_children := DBMS_XMLDOM.getChildNodes (p_node );
l_length := DBMS_XMLDOM.getLength (l_children );
l_i := 0;
WHILE l_i < l_length
LOOP
BEGIN
l_child := DBMS_XMLDOM.item (l_children , l_i );
IF DBMS_XMLDOM.getNodeType (l_child )!= DBMS_XMLDOM.ELEMENT_NODE THEN
BEGIN l_i := l_i + 1; CONTINUE; END; END IF;
l_name := DBMS_XMLDOM.
getLocalName (DBMS_XMLDOM.makeElement (l_child ));
IF l_name = 'member' THEN
BEGIN l_obj .member.add(decode_member(l_child )); END;
END IF;
l_i := l_i + 1;
END;
END LOOP;
RETURN l_obj ;
END;
FUNCTION decode_member (p_node IN DBMS_XMLDOM.DOMNode ) RETURN
member IS
l_obj member ;
l_children DBMS_XMLDOM.DOMNodeList ;
l_length INTEGER ;
l_i INTEGER ;
l_child DBMS_XMLDOM.DOMNode ;
l_name VARCHAR2 (32767);
BEGIN
l_obj := member();
l_children := DBMS_XMLDOM.getChildNodes (p_node );
l_length := DBMS_XMLDOM.getLength (l_children );
l_i := 0;
WHILE l_i < l_length
LOOP
BEGIN
l_child := DBMS_XMLDOM.item (l_children , l_i );
IF DBMS_XMLDOM.getNodeType (l_child )!= DBMS_XMLDOM.ELEMENT_NODE THEN
BEGIN l_i := l_i + 1; CONTINUE; END; END IF;
l_name := DBMS_XMLDOM.
getLocalName (DBMS_XMLDOM.makeElement (l_child ));
IF l_name = 'name' THEN
BEGIN l_obj .name := decode_string(l_child ); END;
END IF;
IF l_name = 'eno' THEN
BEGIN l_obj .eno := decode_string(l_child ); END;
END IF;
l_i := l_i + 1;
END;
END LOOP;
RETURN l_obj ;
END;
FUNCTION decode_string (p_node IN DBMS_XMLDOM.DOMNode ) RETURN VARCHAR2 IS
l_children DBMS_XMLDOM.DOMNodeList ;
l_length INTEGER ;
l_i INTEGER ;
l_child DBMS_XMLDOM.DOMNode ;
l_char_data DBMS_XMLDOM.DOMCharacterData ;
BEGIN
l_children := DBMS_XMLDOM.getChildNodes (p_node );
l_length := DBMS_XMLDOM.getLength (l_children );
l_i := 0;
WHILE l_i < l_length
LOOP
BEGIN
l_child := DBMS_XMLDOM.item (l_children , l_i );
IF DBMS_XMLDOM.getNodeType (l_child )
= DBMS_XMLDOM.TEXT_NODE THEN
BEGIN
l_char_data := DBMS_XMLDOM.makeCharacterData (l_child );
RETURN DBMS_XMLDOM.getData (l_char_data );
END;
END IF;
l_i := l_i + 1;
END;
END LOOP;
RETURN '';
END;
xml encode
FUNCTION encd_root_staff
(p_obj IN OUT staff ) RETURN DBMS_XMLDOM.DOMDocument IS
l_response_node DBMS_XMLDOM.DOMNode ;
l_element DBMS_XMLDOM.DOMElement ;
l_node DBMS_XMLDOM.DOMNode ;
l_fcall_tmp DBMS_XMLDOM.DOMNode ;
BEGIN
XmlResponse.response_doc := DBMS_XMLDOM.newDOMDocument ();
l_response_node := encd_staff (p_obj ,'staff');
l_element := DBMS_XMLDOM.makeElement (l_response_node );
l_node := DBMS_XMLDOM.makeNode (XmlResponse.response_doc );
l_fcall_tmp := DBMS_XMLDOM.appendChild (l_node , l_response_node );
DBMS_XMLDOM.setAttribute (l_element , 'xmlns:ns2',
'http://edb.att.com/cci/v2.0')
;
DBMS_XMLDOM.setAttribute (l_element , 'xmlns:ns1',
'http://cio.att.com/CommonHeader/v2')
;
RETURN XmlResponse.response_doc ;
END;
FUNCTION encd_staff
(p_obj IN OUT staff , p_tag IN VARCHAR2 ) RETURN
DBMS_XMLDOM.DOMNode IS
l_element DBMS_XMLDOM.DOMElement ;
l_node DBMS_XMLDOM.DOMNode ;
l_fcall_tmp DBMS_XMLDOM.DOMNode ;
BEGIN
l_element := DBMS_XMLDOM.createElement (XmlResponse.response_doc ,p_tag );
l_node := DBMS_XMLDOM.makeNode (l_element );
IF p_obj IS NOT NULL THEN
BEGIN
IF p_obj .member.count >0 THEN
for i in 1..p_obj .member.count
loop
BEGIN
l_fcall_tmp := DBMS_XMLDOM.appendChild (l_node ,encode_member(p_obj .member,'member'));
END;
end loop;
END IF;
END;
END IF;
RETURN l_node ;
END;
FUNCTION encd_member
(p_obj IN OUT member , p_tag IN VARCHAR2 ) RETURN
DBMS_XMLDOM.DOMNode IS
l_element DBMS_XMLDOM.DOMElement ;
l_node DBMS_XMLDOM.DOMNode ;
l_fcall_tmp_1 DBMS_XMLDOM.DOMNode ;
l_fcall_tmp DBMS_XMLDOM.DOMNode ;
BEGIN
l_element := DBMS_XMLDOM.createElement (XmlResponse.response_doc ,p_tag );
l_node := DBMS_XMLDOM.makeNode (l_element );
IF p_obj IS NOT NULL THEN
BEGIN
IF p_obj .name IS NOT NULL THEN
BEGIN
l_fcall_tmp := DBMS_XMLDOM.appendChild (l_node ,encode_string(p_obj .name,'name'));
END;
END IF;
IF p_obj .eno IS NOT NULL THEN
BEGIN
l_fcall_tmp := DBMS_XMLDOM.appendChild (l_node ,encode_string(p_obj .eno,'eno'));
END;
END IF;
END;
END IF;
RETURN l_node ;
END;
FUNCTION encode_string (p_obj IN VARCHAR2 , p_tag IN VARCHAR2 ) RETURN
DBMS_XMLDOM.DOMNode IS
l_node4 DBMS_XMLDOM.DOMNode ;
l_fcall_tmp_1 DBMS_XMLDOM.DOMNode ;
l_fcall_tmp DBMS_XMLDOM.DOMNode ;
BEGIN
l_node4 := DBMS_XMLDOM.
makeNode (DBMS_XMLDOM.createElement (XmlResponse.response_doc ,
p_tag ));
IF p_obj IS NOT NULL THEN
BEGIN
l_fcall_tmp := DBMS_XMLDOM.appendChild (l_node4 ,
DBMS_XMLDOM.
makeNode (DBMS_XMLDOM.
createTextNode (XmlResponse.
response_doc ,
p_obj )));
END;
ELSE
BEGIN
l_fcall_tmp_1 := DBMS_XMLDOM.appendChild (l_node4 ,
DBMS_XMLDOM.
makeNode (DBMS_XMLDOM.
createTextNode (XmlResponse.
response_doc ,
' ')));
END;
END IF;
RETURN l_node4 ;
END;