Как насчет (обновлено):
XPath 1.0:
"//div[substring-before(@id, '_') = 'foo'
and substring-after(@id, '_') >= 0
and substring-after(@id, '_') <= 99999999]"
Редактировать # 2: ОП внес изменения в вопрос. Следующее, еще более сокращенное выражение XPath 1.0 работает для меня:
"//div[substring(@id, 1, 13) = 'post_message_'
and substring(@id, 14) >= 0
and substring(@id, 14) <= 99999999]"
XPath 2.0 имеет удобную matches()
функцию :
"//div[matches(@id, '^foo_\d{1,8}$')]"
Помимо лучшей переносимости, я ожидал бы, что числовое выражение (стиль XPath 1.0) будет работать лучше, чем тест регулярного выражения, хотя это станет заметным только при обработке больших наборов данных.
Оригинальная версия ответа:
"//div[substring-before(@id, '_') = 'foo'
and number(substring-after(@id, '_')) = substring-after(@id, '_')
and number(substring-after(@id, '_')) >= 0
and number(substring-after(@id, '_')) <= 99999999]"
Использование функции number()
не является необходимым, поскольку операторы математического сравнения неявно приводят свои аргументы к числам, любые нечисловые значения станут NaN
, и тесты больше / меньше, чем пройдут.
Я также убрал кодировку угловых скобок, поскольку это требование XML, а не требование XPath.