首页 > 解决方案 > 将属性添加到元素 xml

问题描述

我想向我的应答器 xml 添加属性。

    set serveroutput on;
    DECLARE
      doc  xmltype := xmltype(
      '<workbook>
         <worksheet sheetName="MySheet1" sheetId="1"/>
         <worksheet sheetName="MySheet2" sheetId="2"/>
         <worksheet sheetName="MySheet3" sheetId="3"/>
       </workbook>');
    BEGIN
    select updatexml(doc,'workbook','<workbook id="1"></workbook>') into                 doc from dual;            
    dbms_output.put_line(doc.getclobval());
    END; 

但如果我添加我不再有“工作表”标签。

你能帮助我吗 ?

标签: xmloracleplsql

解决方案


如果要向现有节点添加属性,而不是添加其他节点,可以使用insertchildxml

insertchildxml(doc, '/workbook', '@id', '1')

所以在你的代码中:

DECLARE
  doc  xmltype := xmltype(
  '<workbook>
     <worksheet sheetName="MySheet1" sheetId="1"/>
     <worksheet sheetName="MySheet2" sheetId="2"/>
     <worksheet sheetName="MySheet3" sheetId="3"/>
   </workbook>');
  txt clob;
BEGIN
  select insertchildxml(doc, '/workbook', '@id', '1') into doc from dual;            
  dbms_output.put_line(doc.getclobval());
END;
/

<workbook id="1"><worksheet sheetName="MySheet1" sheetId="1"/><worksheet sheetName="MySheet2" sheetId="2"/><worksheet sheetName="MySheet3" sheetId="3"/></workbook>

PL/SQL procedure successfully completed.

或为可读性而格式化:

DECLARE
  doc  xmltype := xmltype(
  '<workbook>
     <worksheet sheetName="MySheet1" sheetId="1"/>
     <worksheet sheetName="MySheet2" sheetId="2"/>
     <worksheet sheetName="MySheet3" sheetId="3"/>
   </workbook>');
  txt clob;
BEGIN
  select insertchildxml(doc, '/workbook', '@id', '1') into doc from dual;            
  select xmlserialize(document doc indent size=2) into txt from dual;            
  dbms_output.put_line(txt);
END;
/

<workbook id="1">
  <worksheet sheetName="MySheet1" sheetId="1"/>
  <worksheet sheetName="MySheet2" sheetId="2"/>
  <worksheet sheetName="MySheet3" sheetId="3"/>
</workbook>


PL/SQL procedure successfully completed.

但是insertchildxml已弃用(原样appendchildxml),因此您可以使用 XMLQuery 来代替:

xmlquery('copy $out := $in modify
    ( insert node attribute id {"1"} into $out/workbook )
    return $out'
  passing doc as "in" returning content)

再次在您的代码中并格式化以供显示:

DECLARE
  doc  xmltype := xmltype(
  '<workbook>
     <worksheet sheetName="MySheet1" sheetId="1"/>
     <worksheet sheetName="MySheet2" sheetId="2"/>
     <worksheet sheetName="MySheet3" sheetId="3"/>
   </workbook>');
  txt clob;
BEGIN
  select xmlquery('copy $out := $in modify
      ( insert node attribute id {"1"} into $out/workbook )
      return $out'
    passing doc as "in" returning content)
  into doc from dual;            
  select xmlserialize(document doc indent size=2) into txt from dual;            
  dbms_output.put_line(txt);
END;
/

<workbook id="1">
  <worksheet sheetName="MySheet1" sheetId="1"/>
  <worksheet sheetName="MySheet2" sheetId="2"/>
  <worksheet sheetName="MySheet3" sheetId="3"/>
</workbook>


PL/SQL procedure successfully completed.

您还可以将属性值传递给 XPath:

DECLARE
  doc  xmltype := xmltype(
  '<workbook>
     <worksheet sheetName="MySheet1" sheetId="1"/>
     <worksheet sheetName="MySheet2" sheetId="2"/>
     <worksheet sheetName="MySheet3" sheetId="3"/>
   </workbook>');
  txt clob;
BEGIN
  select xmlquery('copy $out := $in modify
      ( insert node attribute id {$id} into $out/workbook )
      return $out'
    passing doc as "in", 42 as "id" returning content)
  into doc from dual;            
  select xmlserialize(document doc indent size=2) into txt from dual;            
  dbms_output.put_line(txt);
END;
/

<workbook id="42">
  <worksheet sheetName="MySheet1" sheetId="1"/>
  <worksheet sheetName="MySheet2" sheetId="2"/>
  <worksheet sheetName="MySheet3" sheetId="3"/>
</workbook>


PL/SQL procedure successfully completed.

如果您想添加命名空间作为属性,您可以执行以下操作:

DECLARE
  doc  xmltype := xmltype(
  '<workbook>
     <worksheet sheetName="MySheet1" sheetId="1"/>
     <worksheet sheetName="MySheet2" sheetId="2"/>
     <worksheet sheetName="MySheet3" sheetId="3"/>
   </workbook>');
  txt clob;
BEGIN
  select xmlquery('copy $out := $in modify
      ( insert node attribute {concat("xmlns:", $id)} {$path} into $out/workbook )
      return $out'
    passing doc as "in", 'ns' as "id", 'http://example.com' as "path" returning content)
  into doc from dual;            
  select xmlserialize(document doc indent size=2) into txt from dual;            
  dbms_output.put_line(txt);
END;
/

<workbook xmlns:ns="http://example.com" xmlns:xmlns="http://www.w3.org/2000/xmlns/">
  <worksheet sheetName="MySheet1" sheetId="1"/>
  <worksheet sheetName="MySheet2" sheetId="2"/>
  <worksheet sheetName="MySheet3" sheetId="3"/>
</workbook>


PL/SQL procedure successfully completed.

但是由于您的节点没有名称空间,这似乎有点毫无意义。


推荐阅读