2009-04-13 52 views
6

有誰知道如何使用PL/SQL檢索<ZIPCODE><CITY>的值嗎?我通過網絡學習了一個教程,但是,它可以檢索元素名稱,但不能檢索它們的值。你們誰都知道似乎是什麼問題?我已經諮詢了谷歌(互聯網的保存完好的祕密),在這一點,但沒有運氣:(檢索Oracle PL中xml元素的值SQL

<Zipcodes> 
    <mappings Record="4"> 
    <STATE_ABBREVIATION>CA</STATE_ABBREVIATION> 
    <ZIPCODE>94301</ZIPCODE> 
    <CITY>Palo Alto</CITY> 
    </mappings> 
</Zipcodes> 

這裏的示例代碼:

-- prints elements in a document 
PROCEDURE printElements(doc DBMS_XMLDOM.DOMDocument) IS 
    nl DBMS_XMLDOM.DOMNodeList; 
    n DBMS_XMLDOM.DOMNode; 
    len number; 
BEGIN 
    -- get all elements 
    nl := DBMS_XMLDOM.getElementsByTagName(doc, '*'); 

    len := DBMS_XMLDOM.getLength(nl); 

    -- loop through elements 
    FOR i IN 0 .. len - 1 LOOP 
     n := DBMS_XMLDOM.item(nl, i); 

     testr := DBMS_XMLDOM.getNodeName(n) || ' ' || DBMS_XMLDOM.getNodeValue(n); 

     DBMS_OUTPUT.PUT_LINE (testr); 
    END LOOP; 

    DBMS_OUTPUT.PUT_LINE (''); 
END printElements; 
+0

我個人更喜歡使用XMLType並使用Extract函數通過XPath獲取它們。例如`myxml.Extract('/ Zipcodes/mappings/ZIPCODE/text()');` - 必須比走DOM更簡單。 – 2012-02-08 06:22:28

回答

12

您需要更改線路

testr := DBMS_XMLDOM.getNodeName(n) || ' ' || DBMS_XMLDOM.getNodeValue(n); 

testr := DBMS_XMLDOM.getNodeName(n) || ' ' || DBMS_XMLDOM.getNodeValue(DBMS_XMLDOM.getFirstChild(n)); 

In XML DOM,元素沒有任何「價值」可言。元素節點包含Text節點作爲子節點,並且這些節點包含所需的值。

編輯(回覆Tomalak的評論):我不知道DBMS_XMLDOM中的任何函數來獲取元素的所有子文本節點的組合值。如果這是你需要的東西,那麼你可能需要使用類似下面的功能:

CREATE OR REPLACE FUNCTION f_get_text_content (
    p_node   DBMS_XMLDOM.DOMNode 
) RETURN VARCHAR2 
AS 
    l_children  DBMS_XMLDOM.DOMNodeList; 
    l_child   DBMS_XMLDOM.DOMNode; 
    l_text_content VARCHAR2(32767); 
    l_length   INTEGER; 
BEGIN 
    l_children := DBMS_XMLDOM.GetChildNodes(p_node); 
    l_length := DBMS_XMLDOM.GetLength(l_children); 
    FOR i IN 0 .. l_length - 1 LOOP 
    l_child := DBMS_XMLDOM.Item(l_children, i); 
    IF DBMS_XMLDOM.GetNodeType(l_child) IN (DBMS_XMLDOM.TEXT_NODE, DBMS_XMLDOM.CDATA_SECTION_NODE) THEN 
     l_text_content := l_text_content || DBMS_XMLDOM.GetNodeValue(l_child); 
    END IF; 
    END LOOP; 
    RETURN l_text_content; 
END f_get_text_content; 
/
+0

如果一個節點包含多個後代,該怎麼辦? - 你如何獲得他們的組合文本? – Tomalak 2009-04-13 09:30:05

0

這是如何從文檔中檢索所需的值一個簡單的例子:

declare 
    vDOM  dbms_xmldom.DOMDocument; 
    vNodes dbms_xmldom.DOMNodeList; 
    vXML  xmltype := xmltype('<Zipcodes> 
    <mappings Record="4"> 
    <STATE_ABBREVIATION>CA</STATE_ABBREVIATION> 
    <ZIPCODE>94301</ZIPCODE> 
    <CITY>Palo Alto</CITY> 
    </mappings> 
</Zipcodes>'); 
begin 
    -- create the dom document from our example xmltype 
    vDOM := dbms_xmldom.newDOMDocument(vXML); 
    -- find all text nodes in the dom document and return them into a node list 
    vNodes := dbms_xslprocessor.selectNodes 
       (n   => dbms_xmldom.makeNode(dbms_xmldom.getDocumentElement(vDOM)) 
       ,pattern => '//*[self::ZIPCODE or self::CITY]/text()' 
       ,namespace => null 
      ); 
    -- iterate through the node list 
    for i in 0 .. dbms_xmldom.getlength(vNodes) - 1 loop 
    -- output the text value of each text node in the list 
    dbms_output.put_line(dbms_xmldom.getNodeValue(dbms_xmldom.item(vNodes,i))); 
    end loop; 
    -- free up document resources 
    dbms_xmldom.freeDocument(vDOM);  
end; 

的在上面的輸出結果請求:「)//文本(」

94301 
Palo Alto 

在與圖案上面的例子中的更換的xpath圖案=>結果在輸出:

CA 
94301 
Palo Alto 

ie。文檔中的所有文本。這個主題的許多變化當然可以使用這種技術。