【问题标题】:how to get DOMTEXT with DBMS_XMLDOM on PL/SQL如何在 PL/SQL 上使用 DBMS_XMLDOM 获取 DOMTEXT
【发布时间】:2016-05-28 03:27:11
【问题描述】:

我正在尝试使用 DBMS_XMLDOM 从我的 xml 中获取文本值。 例如在:

<Vehicle>
    <Cars name ="Tesla">Model-S</Cars>
</Vehicle>

我想将“Model-S”作为 Varchar2。 似乎我找不到像 getTextNode/getTextValue 这样的函数。 从 DomText 获取值的正确方法是什么?

到目前为止,我得到了:

set serveroutput on size 1000000; 
DECLARE     
  xmlDomElement         xmldom.DOMElement; 
  xmlDomDokument        xmldom.DOMDocument; 
  v_xml    clob; 
BEGIN           
  v_xml := 
   '<Vehicle> 
      <Car> 
        <Tesla>Model-X</Tesla> 
      </Car> 
    </Vehicle>'; 

  xmlDomDokument := dbms_xmldom.newDomDocument(v_xml) ; 
  xmlDomElement :=  dbms_xmldom.getdocumentelement(xmlDomDokument); 
  xmlDomNode :=  dbms_xmldom.makeNode(xmlDomElement);   
  dbms_output.put_line( 'Print node Vehicle : ' || dbms_xmldom.getnodename(xmlDomNode)); 

  -- Question: is there something like "dbms_xmldom.getTextValue"?   

end; 

提前致谢。

问候, 伊万

【问题讨论】:

    标签: sql database plsql oracle11g xmldom


    【解决方案1】:

    要获取文本节点的值,可以使用 XMLDOM.GETNODEVALUE。但要使用它,您需要获取节点 xmldom.getFirstChild(n) 的第一个子节点。使用下面的块来获取你的输出

    DECLARE     
      xmlDomElement         xmldom.DOMElement; 
      xmlDomDokument        xmldom.DOMDocument; 
      xmlDomNode            xmldom.DOMNode; 
      lv_domnodelist1       dbms_xmldom.DomNodeList;
      lv_domnodelist2       dbms_xmldom.DomNodeList;
      v_xml    clob; 
    BEGIN           
      v_xml := 
       '<Vehicle> 
          <Car> 
            <Tesla>Model-X</Tesla> 
          </Car> 
        </Vehicle>'; 
    
      xmlDomDokument := dbms_xmldom.newDomDocument(v_xml) ; 
      xmlDomElement :=  dbms_xmldom.getdocumentelement(xmlDomDokument); 
      xmlDomNode :=  dbms_xmldom.makeNode(xmlDomElement);   
      lv_domnodelist1 := DBMS_XMLDOM.GETCHILDNODES(xmlDomNode);
    
      For i in 0..dbms_xmldom.getLength( lv_domnodelist1 ) - 1 loop
        xmlDomNode := DBMS_XMLDOM.ITEM(lv_domnodelist1,i);
        lv_domnodelist2 := DBMS_XMLDOM.GETCHILDNODES(xmlDomNode);
        FOR J in 0..dbms_xmldom.getLength( lv_domnodelist2 ) - 1 loop
          xmlDomNode := DBMS_XMLDOM.ITEM(lv_domnodelist2,J);
          dbms_output.put_line( 'Print node Name : ' ||  dbms_xmldom.getnodename(xmlDomNode)); 
          xmlDomNode := DBMS_XMLDOM.getFirstChild(xmlDomNode);
          dbms_output.put_line( 'Print node Value : ' || dbms_xmldom.getnodevalue(xmlDomNode)); 
        end loop;
      end loop;
    end;
    

    【讨论】:

      【解决方案2】:

      在这里遍历 DOM 似乎有点过头了;你可以使用 XQuery:

      select XMLQuery('/Vehicle/Car/Tesla/text()'
        passing XMLType('<Vehicle> 
            <Car> 
              <Tesla>Model-X</Tesla> 
            </Car> 
          </Vehicle>')
        returning content) as model
      from dual;
      
      MODEL             
      ------------------
      Model-X
      

      如果您需要更多信息,您可以获得更多字段;对于多个节点,您可以改用 XMLTable:

      select *
      from XMLTable('/Vehicle/Car'
        passing XMLType('<Vehicle> 
            <Car> 
              <Tesla>Model-X</Tesla> 
            </Car> 
          </Vehicle>')
        columns vehicle_type varchar2(10) path 'local-name(.)',
          vehicle_make varchar2(10) path 'local-name(./*)',
          vehicle_model varchar2(10) path '*'
      );
      
      VEHICLE_TY VEHICLE_MA VEHICLE_MO
      ---------- ---------- ----------
      Car        Tesla      Model-X   
      

      【讨论】:

      • 使用 xmldom 对于解析元素名称或结构未知的 xml 文档非常有用。编写 xmldom 代码可能会很乏味,但是一旦创建,它将对解析整个文档很有帮助
      • @DineshV - 在这里看起来还是有点矫枉过正 *8-) 当然,这个例子可能会大大简化。
      • @AlexPoole 感谢您的展示。这是一种不同的方法。但也绝对正确。
      猜你喜欢
      • 2012-07-14
      • 2021-09-28
      • 2015-07-24
      • 1970-01-01
      • 1970-01-01
      • 2016-11-29
      • 2017-10-06
      • 2016-01-07
      • 1970-01-01
      相关资源
      最近更新 更多