MySQL для обновления атрибута XML

При загрузке данных некоторые атрибуты XML отображаются неправильно, и сейчас я пытаюсь это исправить, но я борюсь с обработкой MySQL этого столбца XML.

Я хочу исправить атрибуты XML (не значения) для всех вхождений поля (с атрибутом 'tag = "520"') с подполем (с атрибутом 'code = "3"'). Запрос ниже возвращает 0 затронутых строк, 1 найденных строк. Любые подсказки о том, как этого добиться.

UPDATE biblioitems
SET marcxml = UpdateXML(marcxml,'datafield[@tag="520"]/subfield[@code="3"]',
                     'datafield[@tag="520"][@ind1="3"]/subfield[@code="a"]')
WHERE biblionumber = '220405';

XML фрагмент включен для ясности:

Оригинальный фрагмент

<datafield tag="300" ind1=" " ind2=" ">
  <subfield code="f">article</subfield>
</datafield>
<datafield tag="520" ind1=" " ind2=" ">
  <subfield code="3">A description of something here</subfield>
</datafield>
<datafield tag="655" ind1=" " ind2=" ">
  <subfield code="a"></subfield>
</datafield>

Что я хочу получить в результате:

<datafield tag="300" ind1=" " ind2=" ">
  <subfield code="f">article</subfield>
</datafield>
<datafield tag="520" ind1="3" ind2=" ">
  <subfield code="a">A description of something here</subfield>
</datafield>
<datafield tag="655" ind1=" " ind2=" ">
  <subfield code="a"></subfield>
</datafield>

Не удалось понять, как выделить изменение в блоке кода (это атрибут ind1 в поле данных tag = "520" и связанные с ним атрибуты подполя)

Ответы на вопрос(3)

Решение Вопроса

UpdateXML должен быть новым XML-фрагментом, которым нужно заменить часть документа, соответствующую XPath, указанному во втором аргументе.

Вы можете создать фрагмент XML, используяExtractValue:

UPDATE biblioitems
SET    marcxml = UpdateXML(marcxml,
         'datafield[@tag="520"]',
         CONCAT(
           '<datafield tag="520" ind1="a" ind2="',
              ExtractValue(marcxml, 'datafield[@tag="520"]/attribute::ind2'),
           '">',
           '  <subfield code="a">',
             ExtractValue(marcxml, 'datafield[@tag="520"]/subfield'),
           '  </subfield>',
           '</datafield>'
         )
       )
WHERE  biblionumber = 220405;

Посмотри на Sqlfiddle.

 Ashimema01 июн. 2012 г., 17:05
Для любого будущего читателя ... точный запрос, который я использовал для получения требуемого результата, был:UPDATE biblioitems_temp SET marcxml = UpdateXML(marcxml, '//datafield[@tag="520"]', CONCAT( '<datafield tag="520" ind1="3" ind2=" ">', ' <subfield code="a">', Extractvalue(marcxml, '//datafield[@tag="520"]/subfield[@code="3"]'), ' </subfield>', '</datafield>' ) ) WHERE Extractvalue(marcxml, '//datafield[@tag="520"]/subfield[@code="3"]') !='';
 Ashimema23 мая 2012 г., 18:50
Cheer, я, очевидно, неправильно понимаю основы аргумента UpdateXML.

UPDATE biblioitems SET marcxml = UpdateXML(marcxml,'datafield[@tag="520"]/subfield[@code="3"]/@code', 'code="a"') WHERE biblionumber = '220405';

Обратите внимание, что функция UpdateXML требует, чтобы был найден существующий узел. Если вы хотите вставить атрибут, вы должны заменить существующий атрибут более чем одним. например, чтобы вставить атрибут d в элемент x:select updateXML('<x a="aaa" b="bbb">xxxxxx<c>cccc</c></x>', 'x/@a', 'a="aaa" d="ddd"')

который хотите переписать, с помощьюattribute::att ось.

Пример кода MySQL для проверки поведения

SELECT UpdateXML('<root><sub att="foo" xatt="bar">Content Text</sub><sec att="etc">Container</sec></root>', '/root/sub/attribute::att', 'att="something"')

Результатом запроса будет

<root><sub att="something" xatt="bar">Content Text</sub><sec att="etc">Container</sec></root>

Помните, чтобы быть конкретным в вашем запросе XPATH, потому что, если несколько целей совпадают, ничего не будет обновлено. (наблюдается при тестировании)

 Peter Brand04 янв. 2017 г., 21:48
Элегантное и простое решение, не требующее перестройки элемента. Вы думали о том, чтобы внести это в документацию по MySQL, Balazs? Я также нашел сокращенную запись Xpath'root/sub/@att' тоже работает.

Ваш ответ на вопрос