如何在Oracle DBMS_XMLDOM中更改XML元素的名称?

时间:2018-04-11 13:37:59

标签: database oracle xmldom

在编写将某些现有XMLTYPE数据组合到另一个XML文档中的函数时,我需要重命名插入数据的文档元素。查看DBMS_XMLDOM documentation似乎只有GetNodeName函数来读取元素名称,但没有SetNodeName函数来更改元素名称。

在使用DBMS_XMLDOM时,如何更改XML元素的名称?或者这只能回到XSL转换?

最小化PL / SQL示例:

DECLARE
  v_ResultDoc XmlDom.DomDocument;
  v_ResultXml XMLTYPE;
  v_ResultNode XmlDom.DomNode;
  v_ClientDoc XmlDom.DomDocument;
  v_ClientXml XMLTYPE;
  v_Node XmlDom.DomNode;  
BEGIN
  v_ResultDoc := XmlDom.NewDomDocument('<Result/>');
  v_ResultNode := XmlDom.MakeNode(XmlDom.GetDocumentElement(v_ResultDoc));

  v_ClientXml := XMLTYPE('<Foo>Some data generated by another function</Foo>');
  v_ClientDoc := XmlDom.NewDomDocument(v_ClientXml);
  v_Node := XmlDom.MakeNode(XmlDom.GetDocumentElement(v_ClientDoc));
  v_Node := XmlDom.AppendChild(v_ResultNode, XmlDom.AdoptNode(v_ResultDoc, v_Node));
  XmlDom.FreeDocument(v_ClientDoc);

  -- TODO: modify XML to <Result><Bar>Some data generated by another function</Bar></Result>
  v_ResultXml := XmlDom.GetXmlType(v_ResultDoc);
  XmlDom.FreeDocument(v_ResultDoc);
END;

1 个答案:

答案 0 :(得分:0)

似乎没有DBMS_XMLDOM函数来重命名元素名称,唯一的选择(不回退到XSL)是生成一个新的父元素,遍历所有子节点,并将它们移动到新的父节点: / p>

DECLARE
  v_ResultDoc XmlDom.DomDocument;
  v_ResultXml XMLTYPE;
  v_ResultNode XmlDom.DomNode;
  v_ClientDoc XmlDom.DomDocument;
  v_ClientXml XMLTYPE;
  v_ClientNode XmlDom.DomNode;
  v_NodeList XmlDom.DomNodeList;
  v_Node XmlDom.DomNode;  
  i INT;
BEGIN
  v_ResultDoc := XmlDom.NewDomDocument('<Result/>');
  v_ResultNode := XmlDom.MakeNode(XmlDom.GetDocumentElement(v_ResultDoc));

  v_ClientXml := XMLTYPE('<Foo>Some data generated by another function</Foo>');
  v_ClientDoc := XmlDom.NewDomDocument(v_ClientXml);
  v_ClientNode := XmlDom.AppendChild(v_ResultNode,
    XmlDom.MakeNode(XmlDom.CreateElement(v_ResultDoc, 'Bar')));
  v_Node := XmlDom.MakeNode(XmlDom.GetDocumentElement(v_ClientDoc));
  v_NodeList := XmlDom.GetChildNodes(v_Node);
  FOR i IN 0..XmlDom.GetLength(v_NodeList)-1 LOOP
    v_Node := XmlDom.Item(v_NodeList, i);
    v_Node := XmlDom.AppendChild(v_ClientNode,
      XmlDom.AdoptNode(v_ResultDoc, v_Node));
  END LOOP;
  XmlDom.FreeDocument(v_ClientDoc);

  v_ResultXml := XmlDom.GetXmlType(v_ResultDoc);
  XmlDom.FreeDocument(v_ResultDoc);

  -- do something with v_ResultXml ...
END;