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;
Смотрите это на http://sqlfiddle.com/.
Вы можете указать целевой атрибут, который хотите переписать, с помощью 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, потому что, если несколько целей совпадают, ничего не будет обновлено. (наблюдается при тестировании)
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"')