Простые числа и XPath
Иногда мы на работе решаем интересные задачки. Вот, например, одна (почти первая) в постановке nop`а:
Частный случай:
Дан такой xml:
<item>1</item>
<item>2</item>
...
<item>N-1</item>
<item>N</item>
</items>
т.е. выписаны все натуральные числа от 1 до N включительно. Про N ничего заранее не известно —
большое, маленькое, еще какое-то — мы не знаем.
Нужно. Написать xpath, выбирающий все item'ы с простыми числами.
Подчеркиваю — xpath.
Т.е. внутри тега xsl:stylesheet должен быть один примерно такой шаблон:
<xsl:copy-of select="......."/>
</xsl:template>
и больше ничего — ни переменных, ни других шаблонов, ни функций.
На выходе будет что-то типа:
<item>3</item>
<item>5</item>
<item>7</item>
...
Решение следующее:
<items>
<xsl:copy-of select="items/item[not(preceding-sibling::item[(last() + 1) mod . = 0 and . != 1]) and . != 1]"/>
</items>
</xsl:template>
Общая задача
Усложненный вариант — все тоже самое, но в xml просто набор item'ов с какими-то натуральными числами
в каком-то порядке, например:
<item>142</item>
<item>73</item>
<item>10000341</item>
<item>10</item>
...
</items>
Решение:
<items>
<xsl:copy-of select="items/item[not(
str:tokenize(str:padding(. - 1, '1'), '')[(last() + 1 ) mod position()= 0 and position() != 1]
)
and . != 1]"/>
</items>
</xsl:template>
Чтобы понять, что тут делается, надо прочитать про функции padding и tokenize на EXSLT.org.
Tags: xml/xsl, xpath