«Развертывание» строки с помощью XSL - PullRequest
0 голосов
/ 04 августа 2009

У нас есть приложение, которое имеет иерархическую структуру групп. Некоторые из групп передаются в этом формате:

/Geography/NA/US/California

Я хотел бы "развернуть" эту строку, чтобы получить набор узлов, подобный следующему:

/Geography
/Geography/NA
/Geography/NA/US
/Geography/NA/US/California

Я знаю, что могу использовать str: tokenize и получить набор узлов примерно так: [Geography, NA, US, California], но я не знаю, как постепенно собирать части вместе.

У меня есть большинство функций exslt , доступных для использования, но нет функций XSLT 2.0.

Любая помощь приветствуется!

Ответы [ 2 ]

2 голосов
/ 04 августа 2009

Это довольно просто в простом XSLT 1.0, все, что вам нужно, это рекурсивная функция, например, так:

<xsl:template name="UnrollString">
  <xsl:param name="string" select="''" />
  <xsl:param name="head"   select="'/'" />

  <xsl:variable name="tail" select="
    concat(
      substring-after($string, $head), 
      '/'
    )
  " />
  <xsl:variable name="lead" select="
    concat(
      $head, 
      substring-before($tail, '/')
    )
  " />

  <xsl:if test="not($tail = '/')">
    <token>
      <xsl:value-of select="$lead" />
    </token>

    <xsl:call-template name="UnrollString">
      <xsl:with-param name="string" select="$string" />
      <xsl:with-param name="head"   select="concat($lead, '/')" />
    </xsl:call-template>
  </xsl:if>
</xsl:template>

Выход для '/Geography/NA/US/California':

<token>/Geography</token>
<token>/Geography/NA</token>
<token>/Geography/NA/US</token>
<token>/Geography/NA/US/California</token>

Обратите внимание, что:

  • Функция ожидает, что строка начинается с разделителя (то есть косой черты), или в слове будет отсутствовать первое слово («География»).
  • Одна косая черта игнорируется.
  • Холодный разделитель легко обобщается и передается как параметр.
  • Вы можете легко построить иерархию, поместив рекурсивный вызов в элемент <token> вместо внешнего.
  • Порядок вывода можно поменять местами (от самого длинного до самого короткого), поместив рекурсивный вызов над элементом <token> вместо него.
  • Вам потребуется использовать функцию расширения node-set(), чтобы преобразовать возвращаемые токены во что-то, что можно использовать в дальнейшем.
0 голосов
/ 04 августа 2009

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

К счастью, это хорошая простая факториально-подобная рекурсия, а не нечто отвратительное, как последовательность Фибоначчи.

...