4

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

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

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

4

2 回答 2

3

您可以在PL/PerlU函数(或 PL/Perl,如果您可以在中预加载 XML::LibXML)中使用XML ::LibXML,如下所示:plperl.on_initpostgresql.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>+

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

于 2012-05-06T06:25:30.063 回答
2

蟒蛇版本:

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')
于 2013-08-26T17:43:46.703 回答