добавить атрибут к элементу xml - PullRequest
0 голосов
/ 10 апреля 2019

Я хочу добавить атрибут к моему balise 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; 

но если я добавлю, у меня больше не будет тегов 'листа'.

Вы можете мне помочь?

1 Ответ

0 голосов
/ 10 апреля 2019

Если вы хотите добавить атрибут к существующему узлу, а не добавить дополнительный узел, вы можете использовать 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.

но поскольку у ваших узлов нет пространств имен, которые кажутся немного бессмысленными.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...