Тестирование элементов в списке - PullRequest
5 голосов
/ 10 декабря 2008

Для таблицы стилей, которую я пишу (фактически для набора из них, каждый из которых генерирует свой выходной формат), мне нужно оценить, присутствует ли определенное значение в списке значений. В этом случае проверяемое значение берется из атрибута элемента. Список, с которым он должен быть проверен, исходит из вызова таблицы стилей и принимается как верхний уровень <xsl:param> (должен быть предоставлен в командной строке, когда я вызываю xsltproc или эквивалентный саксонский вызов). Например, входное значение может быть:

v0_01,v0_10,v0_99

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

То, что я ищу, является чем-то похожим на Perl grep, в котором я могу видеть, содержится ли значение, которое у меня есть в данный момент, в списке. Это можно сделать с помощью подстроковых тестов, но это должно быть умно, чтобы не получить ложноположительный результат (v0_01 не должен совпадать со строкой, содержащей v0_011). Кажется, что единственный нескалярный тип данных, который поддерживает XSL / XSLT, - это набор узлов. Я полагаю, что можно преобразовать список в набор текстовых узлов, но это выглядит как перебор, даже по сравнению с выполнением теста подстроки с дополнительной проверкой границ для предотвращения ложных совпадений.

Ответы [ 2 ]

8 голосов
/ 10 декабря 2008

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

contains(concat(',' $list, ','), concat(',', $value, ','))

вернет логическое значение. Или вы можете использовать один из них:

substring-before(concat('|,' $list, ',|'), concat(',', $value, ','))

или

substring-after(concat('|,' $list, ',|'), concat(',', $value, ','))

Если в результате вы получите пустую строку, $value не будет в списке.

РЕДАКТИРОВАТЬ:

@ Комментарий Димитра верен: substring-before() (или substring-after()) также вернет пустую строку, если найденная строка будет первой (или последней) в списке. Чтобы избежать этого, я добавил что-то в начале и конце списка. Тем не менее contains() является рекомендуемым способом сделать это.

4 голосов
/ 10 декабря 2008

В дополнение к решению XPath 1.0, предоставленному Tomalak,

Используя XPath 2.0 можно токенизировать список значений:

exists(tokenize($list, ',')[. = $value])

оценивается как true() тогда и только тогда, когда $value содержится в списке значений $list

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