Oracle Sql для атрибута с пространством имен

#sql #oracle #oracle10g

#sql #Oracle #oracle10g

Вопрос:

Я пытаюсь добавить атрибут в xml с помощью инструкции Oracle sql. XML хранится в виде данных в столбце таблицы ‘item’. У меня нет проблем с добавлением нового атрибута ‘id’ со значением ‘123’, как указано в приведенном ниже запросе.

 UPDATE item SET item_xml = INSERTCHILDXML(item_xml , '/item','@id', '123') where customer_id = '1';
  

Однако, если я добавлю пространство имен xml и вместо обычного атрибута ‘id’, если я хочу добавить пространство имен типа ‘xml:id’ ниже xml выдает ошибку ‘Недопустимое выражение XPATH‘, пожалуйста, дайте мне знать, как избежать возникновения этой ошибки

 UPDATE item SET item_xml = INSERTCHILDXML(item_xml , '/item','@xml:id', '123') where customer_id = '1';
  

Я понимаю, что мы не используем пространство имен в обычных случаях, однако я привел атрибут ‘id’ в качестве примера, поскольку наше приложение генерирует xml, который используется в другой системе, которая требует атрибутов с пространством имен для нескольких атрибутов.

После обновления xml должен выглядеть примерно так, как показано ниже, пожалуйста, предположите, что атрибут ‘xml: id=»123″‘ изначально отсутствует в xml-блоке таблицы ‘item’ .

 <items>
  <item xml:id="123">Apple</item>
<items>
  

Комментарии:

1. Вы пытаетесь добавить новый элемент с этим идентификатором (в этом случае, откуда берется «Apple»?) или добавить атрибут к существующему элементу? Включение вашего начального XML для этого клиента может быть полезным. Основываясь на вашем результате, ваше первое обновление фактически ничего не сделает.

2. Я добавляю атрибут «id» к существующему xml к элементу «item». ‘Apple’ — это значение элемента ‘item’. Таким образом, xpath будет «/items/item». Первый запрос будет работать после правильного xpath, который является ‘/items/item’, тем не менее, как только вы добавите пространство имен ‘@xml:id’, запрос начнет выдавать ошибку, которая является реальной проблемой, мне нужно ее решение. В случае неправильного xpath либо атрибут не будет установлен, но он не выдаст «Недопустимое выражение XPATH».

3. О … вы действительно все еще используете Oracle 10g?

Ответ №1:

Я не думаю, что это поддерживается.

Вы могли бы использовать modify XPath для этого; с побочным эффектом, что объявление пространства имен отображается в атрибуте, даже если оно уже объявлено в документе; что, надеюсь, не будет касаться вашей системы, расположенной ниже по потоку:

 UPDATE item SET item_xml = XMLQuery('
  copy $n := .
  modify (  
    for $i in $n/items/item[$item][not(@xml:id)]
      return insert node attribute xml:id {$id} into $i
    )
  return $n'
  passing item_xml, 'Apple' as "item", 123 as "id"
  returning content
)
where customer_id = 1;
  
 ITEM_XML
----------------------------------------------------------------------------------
<items>
  <item xml:id="123" xmlns:xml="http://www.w3.org/XML/1998/namespace">Apple</item>
</items>
  

db<>скрипта

Я передал значение элемента и значение идентификатора в качестве параметров, а не жестко кодировал их в XPath; в зависимости от того, где и как вы связываете эти вещи, вы могли бы выполнить одно обновление для всех ваших строк, получая сопоставление элемента / идентификатора из другой таблицы.

Это работает в более поздних версиях Oracle, например, 18c, и, я полагаю, должно работать с 11.2.0.3. Однако это не будет работать в более ранних версиях, поэтому, если вы действительно используете 10g, тогда потребуется другой подход.

Комментарии:

1. Большое спасибо, Алекс, есть ли какой-либо способ предотвратить добавление атрибута xmlns:xml=» w3.org/XML/1998/namespace «. Я вижу, что он добавлен вместе с атрибутом xml: id. Должен ли я выполнить еще один запрос, чтобы удалить его избыточный атрибут «xmlns: xml»? или это может быть подавлено, если вообще?

2. Насколько я вижу, это не добавляется внутренне и не кажется управляемым. Я полагаю, вы могли бы удалить его из окончательного XML / CLOB с помощью replace() , но это немного затруднительно.

3. Спасибо, Алекс!!