2016-12-28 80 views
1

我在PostgreSQL中创建了一个包含XML列的表。我正在使用该列的text数据类型。现在我有被存储在一个场如表中以下一个样本XML:如何在PostgreSQL中比较XML是否相等

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

现在我已经建立,其比较2个XML数据的一个过程。如果发现XML数据返回true,否则返回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; 
+0

显示您的查询不知道你想要什么。 –

+0

@EvanCarroll - 我的功能如下所示 CREATE OR REPLACE FUNCTION comparexml(p_name_in VARCHAR(255),p_xml_data_in文本,出来的p_id整数)AS $ BODY $ DECLARE V_ID整数。 BEGIN SELECT标识INTO v_id FROM雇员 WHERE XML_DATA = p_xml_data_in和 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 $语言plpgsql; – Nik

+0

更新问题和格式的东西... –

回答

-1

随着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) 

但是,它仍然不是很完美:如果什么标签顺序是不同的(我猜的语义将保持不变,即它们应该被认为是相等的,但显然他们不会)

+0

如果您正在比较与eq你不想清理它。你想对它进行规范化。 http://lxml.de/api/lxml.etree._ElementTree-class.html#write_c14n –

0

我不知道为什么你关心一个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。

这就是说,如果这对你很重要,你也许可以bribe the guy who write this answer and committed the xml code。 PostgreSQL的目前还没有一个canonicalxml类型,但它可以实现的,它是在TODO(并可能在那里停留很长一段时间)

XML规范:转换XML文档的规范形式对它们进行比较。 libxml2对此有支持。

+0

我做了一些研究,并尝试了一些实际场景,并且我知道它的问题不是sameline或newline xml的问题(如上所述有问题)。 Postgre可以比较这两种类型的XML。其实这取决于它如何存储在表中。 托弗贾尼提醒不要忘记我这个周末! Nik

+0

- 继续评论以上评论 这里这个xml已经被一个人在一行中发送,但在表中它被存储在两行中(根据在这个评论中给出的例子,它从ng中取出了新行>标签)。这个人不知道它是如何存储在表中的。所以在比较时,他会在单行中传递xml(与插入时通过的方式相同),这将比较存储在2行中的表的xml(来自ng>标记的新行,但这将显而易见给出不同的结果)。 – Nik

+0

- 继续评论。所以实际上这就是差异所在。 如果有人可以帮助,这将是伟大的。 – Nik