Простые числа и XPath

Иногда мы на работе решаем интересные задачки. Вот, например, одна (почти первая) в постановке nop`а:

Частный случай:
Дан такой xml:

<items>
   <item>1</item>
   <item>2</item>
   ...
   <item>N-1</item>
   <item>N</item>
</items>

т.е. выписаны все натуральные числа от 1 до N включительно. Про N ничего заранее не известно —
большое, маленькое, еще какое-то — мы не знаем.

Нужно. Написать xpath, выбирающий все item'ы с простыми числами.
Подчеркиваю — xpath.
Т.е. внутри тега xsl:stylesheet должен быть один примерно такой шаблон:

<xsl:template match="/">
   <xsl:copy-of select="......."/>
</xsl:template>

и больше ничего — ни переменных, ни других шаблонов, ни функций.

На выходе будет что-то типа:

<item>2</item>
<item>3</item>
<item>5</item>
<item>7</item>
...

Решение следующее:

<xsl:template match="/">
       <items>
           <xsl:copy-of select="items/item[not(preceding-sibling::item[(last() + 1) mod . = 0 and . != 1]) and . != 1]"/>
       </items>
</xsl:template>

Общая задача
Усложненный вариант — все тоже самое, но в xml просто набор item'ов с какими-то натуральными числами
в каком-то порядке, например:

<items>
   <item>142</item>
   <item>73</item>
   <item>10000341</item>
   <item>10</item>
   ...
</items>

Решение:

<xsl:template match="/">
       <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: ,
This entry was posted on Sunday, June 21st, 2009 at 7:40 pm and is filed under Задачи. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Leave a Reply

Your comment