XSL: рекурсия против итерации - PullRequest
0 голосов
/ 16 октября 2011

Я пытаюсь понять, как XSL обрабатывает for-each.Сначала я написал рекурсивную функцию выбора значений (отфильтровывает все строки, которые не соответствуют шаблону регулярного выражения) следующим образом:

<!-- Ver.1 -->
<xsl:function name="choose-values">
  <xsl:param name="values" />
  <xsl:param name="pattern" as="xs:string" />

  <xsl:choose>
    <xsl:when test="count($values) = 0" >
      <xsl:sequence select="()" />
    </xsl:when>
    <xsl:otherwise>
      <xsl:variable name="tail"
                    select="choose-values(subsequence($values, 2), $pattern)" />
      <xsl:variable name="value" select="$values[1]" />
      <xsl:sequence select="if (matches($value, $pattern))
                            then ($value, $tail)
                            else $tail" />
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>

Затем я наткнулся на <xsl:for-each> и переписал его следующим образом:

<!-- Ver.2 -->
<xsl:function name="choose-values">
  <xsl:param name="values" />
  <xsl:param name="pattern" as="xs:string" />

  <xsl:for-each select="$values">
      <xsl:if test="matches(., $pattern)">
        <xsl:sequence select="." />
      </xsl:if>
  </xsl:for-each>
</xsl:function>

Эти две версии эквивалентны?(мои тесты показывают так).Я пропускаю некоторые крайние случаи в Вер.2?

Просто, чтобы прояснить ситуацию, это не домашнее задание.Я просто пытаюсь понять различия (если они есть), используя простой пример.

Ответы [ 2 ]

4 голосов
/ 16 октября 2011

Да, оба образца кажутся эквивалентными. Как правило, вам не требуется рекурсия в XSLT, если только обработка одного элемента в последовательности не зависит каким-либо образом от обработки предыдущих элементов. Если каждый элемент обрабатывается независимо от других, вы можете использовать выражения фильтра или выражения сопоставления, одним из которых является xsl: for-each. Преимущество такого подхода (кроме читабельности кода) состоит в том, что вы не навязываете порядок обработки, что дает оптимизатору больше свободы для применения своей магии.

1 голос
/ 16 октября 2011

Эти две версии эквивалентны?(мои тесты показывают так).Я пропускаю некоторые крайние случаи в Ver.2?

Они кажутся , чтобы дать те же самые результаты - трудно сказать, потому что оба фрагмента кода излишне сложны.

Это можно сделать просто: :

<xsl:sequence select="$values[matches(., $pattern)]"/>
...