@ neo, выражение XPath, которое вы перечисляете , не работает , когда я проверяю его.Попробуйте другой набор данных, и вы увидите:
<root>
<item>
<d>2003-05-30T09:00:00</d>
</item>
<item>
<d>2002-05-30T09:00:00</d>
</item>
<item>
<d>2005-05-30T09:00:00</d>
</item>
</root>
Ваш XPath выдает 2003-05-30T09:00:00
, что, очевидно, не является максимальным.
И имеет смысл, что он не работаетпотому что оси previous-sibling :: и follow-sibling :: внутри функций translate () будут давать только одного родственного элемента каждый.Вы пытаетесь провести общее (заданное) сравнение всех братьев и сестер на каждой оси, но первый аргумент translate () должен быть преобразован в строку, прежде чем у оператора общего сравнения появится шанс сделать свое дело. Преобразование набора узлов в строку игнорирует все узлы, кроме первого в порядке документа.
Кроме того, translate(./d, 'TZ:-', '.')
дает результаты, подобные 2003.05.30.09.00.00
.Это не действительное число, кроме «5».Ваши тестовые данные работают только потому, что годы разные.Вы получите лучшие результаты с translate(./d, 'TZ:-', '')
, что даст 20030530090000
.
Алехандро говорит, что это невозможно сделать в XPath 1.0, и он может быть прав.Давайте попробуем это, и, может быть, мы что-то узнаем, даже если у нас ничего не получится.
Далее, я бы попытался использовать общее сравнение вне функции перевода, чтобы оно могло сравнивать целые наборы узлов.Что-то вроде этой наивной попытки:
/root/item[
not(following-sibling::item[
translate($current/d, 'TZ:-', '') <= translate(./d, 'TZ:-', '')])
and not(preceding-sibling::item[
translate($current/d, 'TZ:-', '') <= translate(./d, 'TZ:-', '')])]
Однако это неполно, как показывает псевдопеременная $ current, которая должна ссылаться на самый внешний элемент, который является узлом контекста вне всех предикатов.К сожалению, XPath 1.0 не дает нам способа ссылаться на этот внешний контекст, когда другой контекст был помещен в стек внутренним предикатом.
(Мне кажется, я напоминаю, что некоторые реализации XSLT, такие какможет быть, MSXML, позволит вам сделать это с помощью расширенной функции, такой как current(1)
, но в настоящий момент я не могу найти информацию об этом. В любом случае, вы запросили решение XPath, а current()
не XPath.)
На данный момент я согласен с Алехандро, что в чистом стандартном XSLT 1.0 это невозможно.
Если указать среду, в которой вы используете XPath, например, XSLT, Javascript или XQueryМы можем предложить эффективный способ получить то, что вам нужно.Если это XPath 2.0, у Alejandro есть ваш ответ.
Если у вас XQuery 1.0, он должен поддерживать XPath 2.0, поэтому вы можете использовать решение Alejandro с doc () для доступа к входному XML-документу:
max(doc("myInput.xml")/root/item/d/xs:dateTime(.))