ОБНОВЛЕНИЕ XML, когда есть пространства имен - PullRequest
1 голос
/ 08 января 2020

Мне нужно обновить значение в XML:

<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" 
                  xmlns:o="urn:schemas-microsoft-com:office:office" 
                  xmlns:x="urn:schemas-microsoft-com:office:excel" 
                  xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" 
                  xmlns:html="http://www.w3.org/TR/REC-html40">
            <DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
                <Author>XXXXXX</Author>
                <LastAuthor>UCB User</LastAuthor>
                <Created>2019-10-31T13:04:09Z</Created>
                <Version>14.00</Version>
            </DocumentProperties>
            <a>5</a>
        </Workbook>

В моем случае это XML находится в таблице tt поле xml_val .

XPath цели равен / Рабочая книга / Свойства документа / Создано со значением 2019-10-31T13: 04: 09Z и должно быть заменено на 2020-01-08 .

Я связал этот код:

select UPDATEXML(xml_val,
   '/Workbook/DocumentProperties/Created/text()','2020-01-08',
    'xmlns="urn:schemas-microsoft-com:office:spreadsheet" 
              xmlns:o="urn:schemas-microsoft-com:office:office" 
              xmlns:x="urn:schemas-microsoft-com:office:excel" 
              xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" 
              xmlns:html="http://www.w3.org/TR/REC-html40"').getClobVal() as last
from tt;

//. GetClobVal () в конце концов, потому что ORA-21500: внутренний код ошибки, аргументы: [% s], [% s], [% s], [% s], [% s], [% s], [% s], [% s] ( здесь )

Код выше ничего не меняет. Дело в том, что в теге DocumentProperties объявлено еще одно пространство имен. Но я не знаю, как объявить пространства имен в предложении UPDATE XML.

Когда я пытался обновить значение в / Workbook / a с помощью этого кода, это работает corect:

select UPDATEXML(xml_val,
   '/Workbook/a/text()',2020-01-08,
    'xmlns="urn:schemas-microsoft-com:office:spreadsheet" 
              xmlns:o="urn:schemas-microsoft-com:office:office" 
              xmlns:x="urn:schemas-microsoft-com:office:excel" 
              xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" 
              xmlns:html="http://www.w3.org/TR/REC-html40"').getClobVal() as last
from tt;

Различные комбинации имен, которые я пробовал и не работает:

- 1

xmlns="urn:schemas-microsoft-com:office:spreadsheet" 
xmlns:o="urn:schemas-microsoft-com:office:office" 
xmlns:x="urn:schemas-microsoft-com:office:excel" 
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" 
xmlns:html="http://www.w3.org/TR/REC-html40"

- 2

xmlns="urn:schemas-microsoft-com:office:office"
xmlns:o="urn:schemas-microsoft-com:office:office" 
xmlns:x="urn:schemas-microsoft-com:office:excel" 
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" 
xmlns:html="http://www.w3.org/TR/REC-html40"

- 3

xmlns="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel" 
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" 
xmlns:html="http://www.w3.org/TR/REC-html40"

- 4

xmlns="urn:schemas-microsoft-com:office:office"

ПРИМЕЧАНИЕ. Я не могу удалить объявление пространства имен в теге DocumentProperties, поскольку этот XML является частью Excel- XML формат файла

1 Ответ

1 голос
/ 08 января 2020

Элемент DocumentProperties и его дочерние элементы находятся в пространстве имен urn:schemas-microsoft-com:office:office, которое имеет ярлык o; вам нужно добавить префикс этих элементов к их пространству имен в Xpath:

SELECT UPDATEXML(
         xml_val,
         '/Workbook/o:DocumentProperties/o:Created/text()',
         '2020-01-08',
         'xmlns="urn:schemas-microsoft-com:office:spreadsheet" 
          xmlns:o="urn:schemas-microsoft-com:office:office" 
          xmlns:x="urn:schemas-microsoft-com:office:excel" 
          xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" 
          xmlns:html="http://www.w3.org/TR/REC-html40"'
       ) AS updated_xml
FROM   tt;
| UPDATED_XML                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40"><DocumentProperties xmlns="urn:schemas-microsoft-com:office:office"><Author>XXXXXX</Author><LastAuthor>UCB User</LastAuthor><Created>2020-01-08</Created><Version>14.00</Version></DocumentProperties><a>5</a></Workbook> |

db <> fiddle здесь

Однако, UPDATEXML устарел, и вы должны использовать XMLQUERY:

SELECT XMLQuery(
         'declare default element namespace "urn:schemas-microsoft-com:office:spreadsheet"; (: :)
          declare namespace o = "urn:schemas-microsoft-com:office:office"; (: :)
          copy $i := $x modify 
          ( for $j in $i/Workbook/o:DocumentProperties/o:Created
            return replace value of node $j with $v )
          return $i'
         PASSING xml_val AS "x",
                 '2020-01-08' AS "v"
         RETURNING CONTENT
       ) AS updated_xml
FROM   tt

db <> fiddle здесь

...