Postgresql:如何更改XML列中属性的值?

时间:2012-04-26 07:37:09

标签: xml postgresql plpgsql postgresql-9.1

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

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

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

2 个答案:

答案 0 :(得分:2)

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

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>+

在XPath表达式findnodes()中有很大的灵活性,以防你需要更多。

答案 1 :(得分:0)

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