XSL — список эквивалентных реализаций

Я хотел бы знать, есть ли у нас что-то в XSL 2.0, эквивалентное списку в Java. Я хотел бы рекурсивно вызвать шаблон 10 раз и передать входную переменную с именем «mylist». В шаблоне я хочу выполнять такие операции, как добавление элемента в список, удаление элемента из списка, перебор элементов в списке и т. д. Я мог видеть что-то вроде «последовательности», но я не уверен, можно ли его использовать для добавления, удаления , повторение и т. д. Пожалуйста, поделитесь своими идеями, чтобы реализовать это.

Я попытался использовать последовательность с помощью приведенного ниже ответа, но столкнулся с некоторыми проблемами с синтаксисом, например, с объявлением пустой последовательности. Я хочу напечатать последовательность 1 2 3 4 5 6 7 8 9 10, используя функции вставки перед или последовательностью. Пожалуйста, помогите мне исправить синтаксис.

  <xsl:stylesheet version="2.0" 
  xmlns:locator="http://ntr.lxnx.org"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
  <xsl:template match="/"> 
  <xsl:variable name="output">
  <xsl:call-template name="calculate-data"> 
                <xsl:with-param 
                    name="sequence" 
                    select=""/> 
                 <xsl:with-param 
                    name="count"  
                    select="1"/>
            </xsl:call-template> 
  </xsl:variable>
  <xsl:value-of select="output"></xsl:value-of>
  </xsl:template>  
  <xsl:variable name="main-root" as="document-node()" select="/"/>

  <xsl:template name="calculate-data">
<xsl:param name="sequence"/>
  <xsl:param name="count" select="0"/>
<xsl:if test="$count != 10">
                fn:insert-before($count as item()*,0 as xs:integer,$sequence as item()*)
                <xsl:call-template name="calculate-data"> 
                    <xsl:with-param 
                        name="sequence" 
                        select="$sequence"/> 
                     <xsl:with-param 
                        name="count"  
                        select="$count + 1"/>
                </xsl:call-template>              


</xsl:if> 
        </xsl:template>
        </xsl:stylesheet>

person Rachel    schedule 27.04.2011    source источник
comment
Вы можете повторять последовательности. Вы сможете применять шаблоны к последовательностям в XSLT 3.0. О добавлении/удалении: обратите внимание, что XSLT является декларативным языком, эти функции создадут новый экземпляр.   -  person    schedule 28.04.2011
comment
Рэйчел, возможно, вы могли бы привести небольшой пример того типа ввода/вывода, который вам нужен? Причина, по которой я спрашиваю, заключается в том, что XSL обычно не используется в качестве процедурного языка, поэтому изменение значений в списке по мере его повторения обычно не является идеальным способом решения проблемы. Скорее, вы бы указали, каким должен быть конечный результат, а не как его достичь.   -  person Erica    schedule 28.04.2011
comment
@Erica: Ваша точка зрения очень верна. Я заинтересован в использовании последовательности для достижения решения, потому что я хочу узнать больше. Спасибо за ваш ответ.   -  person Rachel    schedule 29.04.2011


Ответы (1)


С уточнением, что экземпляр последовательности, как и все остальное в XPath/XSLT, является неизменяемым, ответ положительный:

  1. Итерация последовательности:

    <xsl:for-each select="$seq">
     <!-- Whatever necessary code here -->
     <!-- . is the current item of the sequence-->
    </xsl:for-each>
    
  2. Добавить элемент в последовательность (создает новую последовательность, являющуюся результатом этой операции):

       insert-before($target as item()*,
                     $position as xs:integer,
                     $inserts as item()*) as item()*
    

Сводка: возвращает новую последовательность, созданную из значения $target со значением $inserts, вставленным в позицию, указанную значением $position. (На значение $target конструкция последовательности не влияет.)

.3. Объединение двух последовательностей (производит новая последовательность, которая является результатом этой операции):

   $seq1 , $seq2

..4. Удалить элемент из последовательности:

     remove($target as item()*, $position as xs:integer) as item()*

Сводка: возвращает новую последовательность, построенную на основе значения $target, с удаленным элементом в позиции, указанной значением $position.

..5. Извлечь подпоследовательность из последовательности:

   subsequence($sourceSeq as item()*,
               $startingLoc as xs:double,
               $length as xs:double) **as item**()*

Сводка: возвращает непрерывную последовательность элементов в значении $sourceSeq, начиная с позиции, указанной значением $startingLoc, и продолжая количество элементов, указанное значением $length.

И есть много других полезных стандартных функций XPath 2.0 над последовательностями.

Примечание. Единственная функция, которой нет в последовательности XPath 2.0, — это "вложенность". Последовательность всегда «плоская», и элемент последовательности не может быть самой последовательностью. Существуют способы имитации многоуровневых последовательностей — например, элемент может быть узлом, а его дочерние узлы можно рассматривать как вложенную последовательность.

Обновление: вот как можно удобно использовать эти функции для решения обновленного вопроса OP:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema"
 xmlns:my="my:my" >

 <xsl:template match="/">
  <xsl:sequence select="my:populateSequence((), 1, 10)"/>
 </xsl:template>

 <xsl:function name="my:populateSequence" as="xs:integer*">
  <xsl:param name="pSeq" as="xs:integer*"/>
  <xsl:param name="pStart" as="xs:integer"/>
  <xsl:param name="pEnd" as="xs:integer"/>

  <xsl:sequence select=
   "if($pStart gt $pEnd)
      then $pSeq
      else my:populateSequence(($pSeq, $pStart), $pStart+1, $pEnd)
   "/>
 </xsl:function>
</xsl:stylesheet>

Когда это преобразование XSLT 2.0 применяется к любому XML-документу (не используемому), создается желаемый результат:

1 2 3 4 5 6 7 8 9 10
person Dimitre Novatchev    schedule 28.04.2011
comment
Я ценю, что вы делитесь идеями. Я сталкиваюсь с проблемами синтаксиса, реализующими это. Я обновил свой пост с помощью xsl. Пожалуйста, предоставьте свои комментарии, чтобы объявить пустую последовательность и вставить элементы в последовательность. Спасибо. - person Rachel; 29.04.2011
comment
@Rachel: С удовольствием -- я возвращаюсь домой с работы и обновлю свой ответ, когда буду дома. То, о чем вы просите, может быть сделано очень легко и элегантно :) - person Dimitre Novatchev; 29.04.2011
comment
@Rachel: я обновил свой ответ решением вашей новой проблемы. Пожалуйста, задавайте новые вопросы как... новые вопросы. - person Dimitre Novatchev; 29.04.2011
comment
@Rachel: Как видите, для этой простой задачи вам даже не нужен insert-before() - проблема решается только с помощью оператора конкатенации ,. - person Dimitre Novatchev; 29.04.2011
comment
Спасибо Дмитрий. Я обязательно приму ваш комментарий. Это решение идеально. Я хорошо знаком с использованием рекурсивных функций, но не с использованием последовательности. Я пытаюсь понять, как то же самое можно реализовать с помощью последовательности. Пожалуйста, поделитесь своими идеями об использовании последовательности для достижения этой цели. Мне это очень поможет. - person Rachel; 29.04.2011
comment
@Rachel: Что вы имеете в виду под тем, как то же самое можно реализовать с помощью последовательности. ? Мое решение используется с использованием последовательности. - person Dimitre Novatchev; 29.04.2011
comment
Да Дмитрий. Вы правы в том, что приведенное выше решение также использует последовательность и является лучшим способом достижения. В приведенном выше сообщении у вас есть общие функции, такие как insert-before/concat и т. д. В примере вместо того, чтобы элементы в последовательности были целыми числами, я хочу, чтобы они были в виде строки и создавали последовательность, используя предопределенные функции, которые вы предложили до. Я хочу знать, как начать с передачи пустой последовательности в качестве параметра в шаблон, а затем рекурсивно вызвать шаблон для создания полной последовательности элементов. Спасибо за ваш быстрый ответ. - person Rachel; 29.04.2011
comment
@ Рэйчел, для этой простой задачи тебе действительно не нужно insert-before(). Эта функция наиболее необходима, когда элемент нужно вставить не в конец последовательности, а в какую-то среднюю позицию. Вам нужно придумать более сложную задачу (как я уже сказал — представить ее как новый вопрос), которая действительно требует использования других функций последовательности. :) - person Dimitre Novatchev; 29.04.2011
comment
Как насчет использования concat для добавления в конец. После прочтения вашего ответа о функциях последовательности мне очень любопытно узнать ответы на следующие 2 запроса. 1) Использование функции выборки последовательности 2) Передача пустой последовательности в качестве параметра вызову шаблона. Я буду очень рад их видеть. - person Rachel; 29.04.2011
comment
@Rachel: $seq, $item создает новую последовательность, которая является результатом добавления элемента $item в конец последовательности $seq. И выражение $seq1, $seq2 создает новую последовательность, которая является результатом объединения этих двух последовательностей. Вам действительно не нужно ничего другого, чтобы выразить эти операции. :) - person Dimitre Novatchev; 29.04.2011
comment
@Что касается передачи пустой последовательности в функцию, у вас уже есть пример для этого в моем решении - читайте внимательно. - person Dimitre Novatchev; 29.04.2011
comment
Спасибо Дмитрий. Я ценю ваши быстрые ответы. - person Rachel; 29.04.2011
comment
+1 Это действительно хороший ответ. Просто потому, что кто-то может подумать не в общей задаче, а в этой конкретно, 1 to 10 выдаст эту последовательность 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 - person ; 29.04.2011