2016-12-28 2 views
1

Я создал таблицу в PostgreSQL, которая содержит столбец XML. Я использую тип данных text для этого столбца. Теперь у меня есть один пример XML, который хранится в одном поле следующим образом в таблице:Как сравнить XML для равенства в PostgreSQL

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

Теперь я создал одну процедуру, которая сравнивает 2 XML-данных. Если данные XML будет найден, он возвращает истину еще ложь

Проблема, если данные 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 INTEGER; НАЧАТЬ SELECT, идентификатор НА v_id ОТ работника ГДЕ XML_DATA = p_xml_data_in и ИМЯ = 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; – 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 на столе.
  • id в xml.

Это, если это важно для вас, возможно, bribe the guy who write this answer and committed the xml code. PostgreSQL в настоящее время не имеет canonicalxml типа, но она может быть реализована, и это на TODO (и, вероятно, останутся там в течение долгого времени)

XML Canonical: Преобразование XML-документов в каноническую форму, чтобы сравнить их. У libxml2 есть поддержка этого.

+0

Я провел некоторое исследование и попробовал некоторые практические сценарии, и я узнал, что это не проблема с sameline или newline xml (как упоминалось выше обсуждаемый). Postgre может сравнивать оба типа xml. На самом деле это зависит от того, как он хранится в таблице. Tove Яни Напоминание Не забывайте меня в эти выходные! Nik

+0

- continue of above comment Здесь этот xml был отправлен человеком одной строкой, а в таблице он хранится в двух строках (в соответствии с примером, приведенным в этом комментарии, для него взята новая строка из ng > тег). Человек не знает, как он хранится в таблице. Поэтому при сравнении он передаст xml в одной строке (точно так же, как он прошел во время вставки), который будет сравнивать xml таблицы, которая хранится в 2 строках (новая строка из тега ng>, которая будет, но очевидна дать другой результат). – Nik

+0

- Продолжение вышеуказанного комментария. Так вот, в чем разница. Если кто-то может помочь в этом, это будет здорово. – Nik

Смежные вопросы