【问题标题】:MySQL to update an XML attributeMySQL 更新 XML 属性
【发布时间】:2012-05-23 11:13:22
【问题描述】:

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

我想更正所有出现的带有子字段(带有属性'code="3"')的字段(带有属性'tag="520"')的XML属性(非值)。下面的查询返回 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 属性及其关联的子字段属性)

【问题讨论】:

    标签: mysql sql xml marc


    【解决方案1】:

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

    【讨论】:

    • 优雅而简单的解决方案,不需要重新构建元素。您是否想过将其贡献给 mySQL 文档 Balazs?我还发现速记 Xpath 符号 'root/sub/@att' 也有效。
    【解决方案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 上查看。

    【讨论】:

    • 干杯,我显然误解了 UpdateXML 参数的基本原理。
    • 对于任何未来的读者......我用来获得所需结果的确切查询是:UPDATE biblioitems_temp SET marcxml = UpdateXML(marcxml, '//datafield[@tag="520"]', CONCAT( '&lt;datafield tag="520" ind1="3" ind2=" "&gt;', ' &lt;subfield code="a"&gt;', Extractvalue(marcxml, '//datafield[@tag="520"]/subfield[@code="3"]'), ' &lt;/subfield&gt;', '&lt;/datafield&gt;' ) ) WHERE Extractvalue(marcxml, '//datafield[@tag="520"]/subfield[@code="3"]') !='';
    【解决方案3】:

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

    请注意,UpdateXML 函数需要找到现有节点。如果要插入一个属性,则必须用多个替换现有属性。例如在 x 元素中插入属性 d: select updateXML('&lt;x a="aaa" b="bbb"&gt;xxxxxx&lt;c&gt;cccc&lt;/c&gt;&lt;/x&gt;', 'x/@a', 'a="aaa" d="ddd"')

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-01
      • 1970-01-01
      相关资源
      最近更新 更多