PostgreSQL XMLPARSE: документ и извлечение значений XPath
XMLPARSE(DOCUMENT text) преобразует строку с XML-документом в тип xml и проверяет корректность его структуры. У документа должен быть один корневой элемент. CONTENT допускает фрагмент, но функции XPath в PostgreSQL ожидают полноценный документ.
Полный пример без создания таблиц
WITH parsed AS (
SELECT XMLPARSE(DOCUMENT $xml$
<employees>
<employee><name>John Doe</name><salary>5000</salary></employee>
<employee><name>Jane Smith</name><salary>6000</salary></employee>
</employees>
$xml$) AS doc
)
SELECT xpath('/employees/employee/name/text()', doc) AS names
FROM parsed;Запрос возвращает одну строку с массивом двух XML-значений: John Doe и Jane Smith. Результат xpath имеет тип xml[], а не одну строку с разделителями. Dollar-кавычки ограничивают SQL-строку; это не дополнительная часть XML.
Получить текстовые строки
WITH parsed AS (
SELECT XMLPARSE(DOCUMENT
'<employees><employee><name>John Doe</name></employee></employees>'
) AS doc
)
SELECT item.name
FROM parsed
CROSS JOIN LATERAL XMLTABLE(
'/employees/employee' PASSING doc
COLUMNS name text PATH 'name'
) AS item;Здесь XMLTABLE превращает выбранные узлы в строки с текстовым полем name. Для этого XML получится одна строка John Doe. Если у реального документа задан namespace, добавьте соответствующее отображение пространства имён; XPath без него не найдёт элементы, даже если имена выглядят одинаково.
Проверить вход и обработать ошибки
SELECT xml_is_well_formed_document('<root><item>ok</item></root>');
-- true
SELECT xml_is_well_formed_document('<root>');
-- falseНеправильный XML в XMLPARSE приводит к ошибке, а не к молчаливому исправлению тегов. Проверка well-formedness не означает соответствие XSD или DTD: встроенный тип xml не выполняет такую схему-валидацию. Установка PostgreSQL также должна поддерживать libxml.
XML, поступающий от пользователя, передавайте как параметр запроса, а не конкатенируйте в SQL. До разбора ограничьте размер документа. Если приложение дополнительно обрабатывает XML вне PostgreSQL, отдельно настройте безопасность именно этого парсера и его внешних сущностей.