Открыть список
Как стать автором
Обновить

Комментарии 22

>> Первоисточник
Это не первоисточник, это копи-cпи$динг
лолик. это мой сайт:)
Т.е. вы все свои статью сюда собираетесь копи-пастить?

Я к тому, что в вашей «оригинальной» статье есть ссылка «Первоисточник», которая ведет на саму себя. Вы когда копипастите сюда или отсюда в блог, хоть смотрите, как копируете.
Сколько злости то…
Подготовил статью для публикаций, в чем проблема?

Забыл в оригинале убрать — сейчас уберу.
Злость — это, кажется, у читателей: вот и коммент заминусовали; я просто обратил ваше внимание на досадную оплошность.

P.S. Правила Хабра в явном виде запрещают кросс-постинг; надеюсь, у вас не будет проблем.
/ — это не узел, это указатель на сам корень. Т.е. используя / вы переводите XPath на поиск от корня документа

// — тоже не совсем верно — это не множество узлов, это указание на произвольную глубину поиска указанной ноды. Т.е. //row найдет вам и /item/row и /item/mynest/row и /item/mynest/subtree/subnest/pod/row.

Ну еще дополню — [] это не аналог (), ну не то что бы не аналог, просто для людей не знающих синтаксиса РНР совсем непонятно.
[] — это предикат, который проверяется на истинность ( т.е. проверяемая строка попадет в результат если все ее предикаты истинны. Добавлю что можно писать несколько предикатов подряд, чтобы легче читалось.

И еще, насколько я вижу, ваше выражение людей не работающих в IBM — неверное, banned у василия говорит от том что он уже тоже НЕ работает в IBM
//row[name[not(@company='ibm')]]

правильнее будет еще добавить проверку статуса
//row[name[@company !='ibm' or @status !='banned']]

Вообще, насколько мне известно — почти во всех языках XPath очень дорогое (ресурсоемкое) удовольствие (особенно если система не затачивалась специально под работу через xpath), так что называя это достойной заменой, надо делать определенные оговорки, а то все достоинства испарятся.

Как пример — буквально в пятницу в небольшой утилите надо было разбирать 15 метров xml фрагментов. Оказалось ГОРАЗДО выгоднее переложить все 15000 записей об объектах в память, в большую хэш-таблицу, чем каждый раз гонять xpath и извлекать только конкретный объект для текущей итерации.
Добавлю еще — на мой взгляд, статья слабовата для того чтобы быть достойной быть написанной :). Подобные базовые знания легко можно почерпнуть в любом источнике. А вот допущенные неточности и ошибки — могут ввести в заблуждение неопытных товарищей.
// неверное, banned у василия говорит от том что он уже тоже НЕ работает в IBM
Я хотел больше показать работу, а не нагружать логикой пример)

спасибо за поправки
welcome to nitpicker corner :)
Эмоциональная реакция: скучно.

По существу: ни заголовок, ни текст до хабраката не дают понять, что игры будут не только XPath, но и с PHP. Так же информация достаточно поверхностная. Проверили бы хотя бы работу библиотеки с юникодом (UTF-8, UTF-16).
Как при помощи XPath можно выбрать элемент с максимальным значением атрибута?
Простой ответ — никак. Эта задача выходит за рамки задач XPath.

Сложный ответ — задать условие, когда значение атрибута найденного элемента будет выше предыдущего найденного значения атрибута. Но учтите — это будет работать весьма медленно. Намного лучше будет просто найти все нужные элементы и уже непосредственно средствами своего языка программирования выполнить поиск наибольшего.
item[not(../item/@attr > @attr)]
item[not((preceding-sibling::item | following-sibling::item)/@attr > @attr)]
имхо — отсортировать и взять первый. Но это уже действительно — уже xslt
В XPath2.0 есть функция max. Правда XSLT2.0 процессоров мало. К примеру: saxon.sourceforge.net/
Понял, в необходимо окунуться в более сложные схемы и показать как это.
Взял на заметку.
Есть ощущение, что автор изучал XPath по примерам, не читая документацию. Пожалуйста, не вводите читателей в заблуждение:

/ не просто узел, а корневой узел;
// не множество узлов, а сокращение для /descendant-or-self::node()/;
* выбирает не любые символы, а только дочерние узлы-элементы (например, сюда не попадают текстовые узлы).

Вместо //row[name[@company='ibm']] лучше писать //row[name/@company='ibm'].
Это я и имел ввиду, нечетко написал.
> Вместо //row[name[@company='ibm']] лучше писать //row[name/@company='ibm']
Это не одно и то же. В первом случае мы перебираем все теги name и проверяем их атрибут. Во втором сравниваем *последовательность* name/@company со строкой. Xslt2.0 процессоры будут сильно ругаться на такое.
Насколько я знаю, в XPath 1.0 сравнивается набор узлов. Не могли бы вы объяснить, на что именно ругаются процессоры XSLT 2.0? В документации ничего подозрительного не нашёл.
Ругаются на ошибку преобразования типов. В документации, если поискать «compatibility mode», всякие «raise error» очень часто встречается рядом.

Вполне возможно конкретно данное выражение сработает. Вполне возможно, сработает корректно. На часах 2:20 проверять лень, извините…

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

ЗЫ: Безусловно, есть XPath 1.0 compatibility mode, но и он не всегда спасает.
ЗЗЫ: www.ozon.ru/context/detail/id/3964217/ вот тут об этом написано на странице 38.
В свете наличия хорошего перевода спецификации на русский язык ценность данного материала сомнительна. А уж при таком количестве неточностей да еще кросспостингом и вовсе входит в минус.
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.