如何在PostgreSQL中比较XML以保持平等



我在PostgreSQL中创建了一个包含XML列的表。我正在使用该列的text数据类型。现在,我有一个样本XML,该XML存储在一个字段中,如表:

<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>

现在,我创建了一个比较2个XML数据的过程。如果找到XML数据,它将返回true else false

问题是XML数据是否存储在表中的一行中,例如

<note><to>Tove</to><from>Jani</from><heading>Reminder</heading><body>Don't forget me this weekend!</body></note>

然后给出所需的输出,但是如果将其存储在不同的行中,则返回null

我的过程看起来像以下

CREATE OR REPLACE FUNCTION comparexml(p_name_in VARCHAR(255), p_xml_data_in text, out p_id integer)AS $BODY$
DECLARE
V_ID INTEGER;
BEGIN
SELECT id INTO v_id
FROM employee 
WHERE XML_DATA = p_xml_data_in and
NAME=p_name_in;

IF(v_id IS NULL) THEN
V_ID := 0;
ELSE
V_ID := 1;
END IF;
p_id=v_id;
END;
$BODY$ LANGUAGE plpgsql;

我不确定为什么您在乎一个XML文档是否等于另一个文档。如果您正在使用此资格搜索,那么您可能(但不确定)做错了。这不是XML的目的。您可以搜索XML中的某些东西。

CREATE TABLE foo AS SELECT xmlparse(DOCUMENT xml) AS xmlcol
FROM ( VALUES
  ($$<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
$$),
  ($$ <note><to>Tove</to><from>Jani</from><heading>Reminder</heading><body>Don't forget me this weekend!</body></note> $$)
) AS t(xml);

但是您不应该关心foo.xmlcol = p_xml_data_in。尝试

  • 桌子上的ID。
  • XML中的ID。

也就是说,如果这对您很重要,则可能会贿赂编写此答案并提交XML代码的人。PostgreSQL当前没有canonicalxml类型,但可以实现,并且它在TODO上(并且很可能待在那里很长一段时间)

XML规范:将XML文档转换为规范形式以比较它们。libxml2对此有所支持。

在plpython和lxml的一点帮助下,您可以清除XML:

CREATE OR REPLACE FUNCTION xmlclean(xml_doc text) RETURNS text AS
$BODY$
from lxml import etree
parser = etree.XMLParser(remove_blank_text=True)
return etree.tostring(etree.XML(xml_doc, parser=parser))
$BODY$
LANGUAGE plpythonu;

示例用法:

postgres=# select xmlclean('<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don''t forget me this weekend!</body>
</note>');
                                                             xmlclean                                             
------------------------------------------------------------------------------------------------------------------
 <note><to>Tove</to><from>Jani</from><heading>Reminder</heading><body>Don't forget me this weekend!</body></note>
(1 row)

和:

postgres=# select xmlclean('<note><to>Tove</to><from>Jani</from><heading>Reminder</heading><body>Don''t forget me this weekend!</body></note>');
                                                     xmlclean                                                     
------------------------------------------------------------------------------------------------------------------
 <note><to>Tove</to><from>Jani</from><heading>Reminder</heading><body>Don't forget me this weekend!</body></note>
(1 row)

但是,它仍然并不完美:如果标签订单不同(我想语义会保持不变,即它们应该被视为平等,但显然不会)

最新更新