Intereting Posts

Получить значение элемента xml в Oracle PL SQL

Кто-нибудь знает, как получить значения <ZIPCODE> и <CITY> с помощью PL / SQL? Я следил за учебником по сети, однако он может извлекать имена элементов, но не их значения. Кто-нибудь из вас знает, какая проблема? Я уже консультировался с Google (секретный секрет в Интернете) по этому поводу, но не повезло 🙁

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

Вам нужно изменить линию

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

в

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

В XML DOM элементы не имеют никакой «ценности», о которых можно говорить. Узлы элементов содержат текстовые узлы в качестве дочерних элементов, и именно эти узлы содержат нужные значения.

EDIT (в ответ на комментарий Томалака): я не знаю каких-либо функций в 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; / 

Это простая иллюстрация того, как получить желаемые значения из документа:

 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 в приведенном выше примере шаблоном => '// text ()' приводит к выводу:

 CA 94301 Palo Alto 

то есть. весь текст в документе. Разумеется, многие варианты этой темы можно использовать с использованием этой техники.