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