2008-12-10 6 views
5

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

v0_01,v0_10,v0_99 

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

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

ответ

8

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

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

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

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

или

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

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

EDIT:

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

+0

На самом деле, для моих целей, это похоже на функцию «содержит» (с помощью предлагаемого дополнения). Что меня подстегнуло, было то, что я искал эту функциональность в самом XSLT, когда я должен был искать XPath. – rjray 2008-12-10 14:20:24

+0

Добавлена ​​функция contains(), которую мне удалось избежать. Благодарю. :-) – Tomalak 2008-12-10 14:29:32

4

В дополнение к 1,0 раствора XPath, предоставленной Томалак,

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

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

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

Смежные вопросы