【问题标题】:Postgresql: How to change the value of an attribute in an XML column?Postgresql:如何更改 XML 列中属性的值?
【发布时间】:2012-04-26 07:37:08
【问题描述】:

在返回给客户端之前,我需要使用表中的 XML 数据类型更改存储在列中的 XML 属性的值。

现在我使用游标,获取xml将其转换为VARCHAR,解析它,更改属性值(如果不存在则添加),将其放入临时表并从临时表返回数据。一切都在一个存储过程(pl/pgsql)中完成。

我想知道是否有更清洁的方法来做到这一点?

【问题讨论】:

  • 我不知道在 XML 中替换属性的函数。但也许你的代码仍然可以改进。如果将其包含在问题中会有所帮助。

标签: xml postgresql plpgsql postgresql-9.1


【解决方案1】:

您可以在PL/PerlU 函数中使用XML::LibXML(或PL/Perl,如果您可以在plperl.on_init 中预加载XML::LibXML 在postgresql.conf 中),如下所示:

CREATE EXTENSION IF NOT EXISTS plperlu;

CREATE OR REPLACE FUNCTION replace_attribute(
    xml   xml,
    attr  text,
    val   text
) RETURNS XML LANGUAGE plperlu AS $$
    my ($xml, $attr, $val) = @_;
    use XML::LibXML;
    my $dom = XML::LibXML->load_xml(string => $xml);
    for my $elem ($dom->findnodes("*[\@$attr]")) {
        $elem->setAttribute($attr => $val);
    }
    return $dom->serialize;
$$;

那么你可以这样使用它:

try=# SELECT replace_attribute(
    '<foo id="blah">hi</foo>',
    'id',
    'whatever'
);
      replace_attribute      
-----------------------------
 <foo id="whatever">hi</foo>+

findnodes() 的 XPath 表达式具有相当大的灵活性,以防您需要更多。

【讨论】:

  • 谢谢,还有一个问题:我需要将 xml 数据类型转换为字符串还是 pl/perl 可以直接使用 xml 数据类型?如果这个函数会被大量调用,我是否应该担心开销?
  • 它将在传递给 PL/Perl 之前自动转换为文本。这就是这里的示例所做的。
【解决方案2】:

Python 版本:

create or replace function replace_attrib(data xml, attr text, val text)
returns xml as
$$
import xml.etree.ElementTree as ET
r = ET.fromstring(data)
r.attrib[attr] = val
return ET.tostring(r)
$$ language plpython3u;

select replace_attrib('<foo id="blah">hi</foo>', 'id', 'whatever')

【讨论】:

    猜你喜欢
    • 2014-03-23
    • 2015-03-22
    • 2010-09-26
    • 2014-05-20
    • 1970-01-01
    • 1970-01-01
    • 2014-09-01
    • 2021-12-24
    • 1970-01-01
    相关资源
    最近更新 更多