MySQL更新XML属性

时间:2012-05-23 11:13:22

标签: mysql sql xml marc

在数据加载中,似乎某些XML属性映射不正确,我现在正在尝试纠正这个问题,但我正在努力解决MySQL对此XML列的处理问题。

我想更正所有字段的出现(属性为'tag =“520”')的XML属性(Not Values)和子字段(属性'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>

无法解决如何突出显示代码块中的更改(它是tag =“520”数据字段中的ind1属性及其相关的子字段属性)

3 个答案:

答案 0 :(得分:2)

UpdateXML的第三个参数应该是新的XML片段,用于替换第二个参数中给出的XPath匹配的文档部分。

您可以使用ExtractValue创建XML片段:

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上查看。

答案 1 :(得分:2)

您可以使用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查询中具体说明,因为如果多个目标匹配,则不会更新任何内容。 (通过测试观察)

答案 2 :(得分:0)

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"')