Postgresql – XML – обработка xpath со сравнением дат

Я вставил XML-файл в базу данных Postgresql и пытаюсь выполнить операцию XPATH над полем со сравнением дат, но она не работает. На официальном сайте Postgresql я узнал, что Postgresql использует Xpath1, а Xpath1 не поддерживает сравнение дат. Я попытался изменить свой запрос Xpath, чтобы использовать сравнение на основе строк, но он все равно не соответствует.

Входной Xpath:

//val:key[@modifiedDate>"2024-06-06"]

Поскольку прямое сравнение дат недоступно в Xpath1, я попробовал сравнение на основе строк.

Преобразованный Xpath:

//val:key[substring(@modifiedDate, 1, 10) > "2024-06-06"]

Но этот XPath также не соответствует, хотя соответствующий Xpath существует. Как мне создать свой Xpath, чтобы он соответствовал полю с датой.

Пример структуры XML, вставленной в таблицу.

<root xmlns:val = "http://some.uri">
    <val:key modifiedDate = "2024-06-07T12:34:56">Key1</val:key>
    <val:key modifiedDate = "2024-06-05T08:21:00">Key2</val:key>
    <val:key modifiedDate = "2024-06-10T14:22:33">Key3</val:key>
    <val:key modifiedDate = "2024-06-06T09:00:00">Key4</val:key>
</root>

Ожидаемый результат: мы сможем сопоставить этот XML, поскольку он имеет xpaths <val:key ModifiedDate="2024-06-07T12:34:56">Key1</val:key> и <val:key ModifiedDate="2024- 06-10T14:22:33">Key3</val:key>, поскольку их атрибуты ModifiedDate начинаются с дат позже, чем "2024-06-06".

SQL-запрос для воспроизведения проблемы:

CREATE TABLE xml_data (
    id SERIAL PRIMARY KEY,
    document XML
);

INSERT INTO xml_data (document)
VALUES ('<root xmlns:val = "http://some.uri">
            <val:key modifiedDate = "2024-06-07T12:34:56">Key1</val:key>
            <val:key modifiedDate = "2024-06-05T08:21:00">Key2</val:key>
            <val:key modifiedDate = "2024-06-10T14:22:33">Key3</val:key>
            <val:key modifiedDate = "2024-06-06T09:00:00">Key4</val:key>
        </root>');

Запрос для фильтрации данных:

SELECT 
    id, document
FROM 
    xml_data
WHERE 
    xpath_exists('//val:key[substring(@modifiedDate, 1, 10) > "2024-06-06"]', document);

Добавьте фиктивные данные и ожидаемые результаты, чтобы сообщество могло помочь.

Pepe N O 04.07.2024 16:54

Задавая вопрос, вам необходимо предоставить минимальный воспроизводимый пример: (1) DDL и образец набора данных, т. е. таблицы CREATE плюс операторы SQL INSERT. (2) Что вам нужно сделать, то есть логику и попытку вашего кода реализовать ее в SQL. (3) Желаемый результат, основанный на примере данных в пункте 1 выше. (4) Ваша версия СУБД.

Yitzhak Khabinsky 04.07.2024 17:06

Изменил вопрос @YitzhakKhabinsky

The6thSense 04.07.2024 18:41

Изменил вопрос @PepeNO

The6thSense 04.07.2024 18:41

В предоставленном образце XML есть одна фундаментальная проблема: в нем нет объявления пространства имен XML. Это делает XML неправильно сформированным и непригодным для использования. Пожалуйста, исправьте это.

Yitzhak Khabinsky 04.07.2024 19:09

Добавьте <root xmlns:val = "http://some.uri">, чтобы определить неопределенное пространство имен «val».

Pepe N O 04.07.2024 19:30

DOne, спасибо вам обоим

The6thSense 08.07.2024 13:42
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
7
56
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Учитывая , что

В XPath 1.0 нет оператора сравнения порядка строк. Оба «кошки» < «собака» и «кошка» > «собака» являются ложными, поскольку каждое из них представляет собой числовое значение. сравнение двух NaN.

Вы можете получить доступ к значениям в своем XML-документе и привести их к дате или метке времени, а затем выполнить сравнение таким образом (исправив отсутствующее пространство имен xmlns:val="http://some.uri", чтобы сделать его действительным):

select key, modified_date from
xmltable(xmlnamespaces('http://some.uri' as val),
'//val:key'
passing (select document from xml_data) 
columns key varchar path 'text()',  
modified_date timestamp path '@modifiedDate')
where modified_date>'2024-06-06';

Результат

ключ модифицированная_дата Ключ1 2024-06-07 12:34:56.000 Ключ3 2024-06-10 14:22:33.000 Ключ4 2024-06-06 09:00:00.000

Скрипка для проверки

Спасибо, я смог решить эту проблему с помощью XPath //val:key[number(translate(substring(@modifiedDate, 1, 10), "-", "")) < number("20240606")]

The6thSense 08.07.2024 19:10
Ответ принят как подходящий

Как указывает Пепе Н О, использование оператора > в выражении XPath преобразует операнды даты из строк в числа, но поскольку оба операнда содержат нечисловые символы, преобразование приведет к NaN в обоих случаях.

Однако вы можете изменить выражение XPath, чтобы использовать функцию перевода XPath для преобразования дат в чисто числовые значения.

Например, выражение translate('2024-06-07T12:34:56', '-T:', '') равно "20240607123456".

Спасибо, я смог решить эту проблему с помощью XPath //val:key[number(translate(substring(@modifiedDate, 1, 10), "-", "")) < number("20240606")]

The6thSense 08.07.2024 19:11

Другие вопросы по теме