Действительно ли возможно отрезать конец URL с XSLT 1.0?

Только Используя XSLT 1.0's строковые функции, как я пошел бы об отрезании конца URL?

Таким образом от

http://stackoverflow.com/questions/2981175/is-it-possible-to-slice-the-end-of-a-url-with-xslt-1-0

Я хотел бы извлечь

is-it-possible-to-slice-the-end-of-a-url-with-xslt-1-0

Действительно ли это возможно?

7
задан Eric 30 June 2012 в 11:40
поделиться

2 ответа

К сожалению, в XSLT / XPath 1.0 нет функции подстроки после последней. Итак, чтобы получить последнюю часть URL-адреса, вам нужно будет написать рекурсивный шаблон, как объяснил Джени Тениссон :

<xsl:template name="substring-after-last">
  <xsl:param name="string" />
  <xsl:param name="delimiter" />
  <xsl:choose>
    <xsl:when test="contains($string, $delimiter)">
      <xsl:call-template name="substring-after-last">
        <xsl:with-param name="string"
          select="substring-after($string, $delimiter)" />
        <xsl:with-param name="delimiter" select="$delimiter" />
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise><xsl:value-of select="$string" /></xsl:otherwise>
  </xsl:choose>
</xsl:template>

Этот шаблон будет вызываться, например, вот так:

<xsl:call-template name="substring-after-last">
  <xsl:with-param name="string" select="$url" />
  <xsl:with-param name="delimiter" select="'/'" />
</xsl:call-template>
7
ответ дан 7 December 2019 в 03:11
поделиться

I. Использование рекурсивно вызываемого именованного шаблона:

Это преобразование:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>

 <xsl:template match="/">
  <xsl:call-template name="eatAllSlashes">
   <xsl:with-param name="pText" select="."/>
  </xsl:call-template>
 </xsl:template>

 <xsl:template name="eatAllSlashes">
  <xsl:param name="pText"/>

  <xsl:choose>
    <xsl:when test="not(contains($pText,'/'))">
      <xsl:value-of select="$pText"/>
    </xsl:when>
    <xsl:otherwise>
     <xsl:call-template name="eatAllSlashes">
       <xsl:with-param name="pText"
        select="substring-after($pText, '/')"/>
     </xsl:call-template>
    </xsl:otherwise>
  </xsl:choose>
 </xsl:template>
</xsl:stylesheet>

при применении к данному XML-документу:

<t>http://stackoverflow.com/questions/2981175/is-it-possible-to-slice-the-end-of-a-url-with-xslt-1-0</t>

производит желаемый, правильный вывод:

is-it-possible-to-slice-the-end-of-a-url-with-xslt-1-0

II. Использование библиотеки FXSL:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my" exclude-result-prefixes="xsl my">
 <xsl:import href="iter.xsl"/>

 <xsl:output method="text"/>

  <my:condition/>
  <my:skipSlash/>

  <xsl:variable name="vfunCondition"
   select="document('')/*/my:condition"/>

  <xsl:variable name="vfunSkipSlash"
   select="document('')/*/my:skipSlash"/>

  <xsl:template match="/">
    <xsl:call-template name="iterUntil">
      <xsl:with-param name="pCond" select="$vfunCondition"/>
      <xsl:with-param name="pFun" select="$vfunSkipSlash"/>
      <xsl:with-param name="arg1" select="string(/)"/>
    </xsl:call-template>
  </xsl:template>

  <xsl:template match="my:condition">
    <xsl:param name="arg1"/>

    <xsl:value-of select="number(not(contains($arg1, '/')))"/>
  </xsl:template>

  <xsl:template match="my:skipSlash">
    <xsl:param name="arg1"/>

    <xsl:value-of select="substring-after($arg1, '/')"/>
  </xsl:template>
</xsl:stylesheet>

Когда это преобразование применяется к этому XML документу:

<t>http://stackoverflow.com/questions/2981175/is-it-possible-to-slice-the-end-of-a-url-with-xslt-1-0</t>

получается желаемый результат:

is-it-possible-to-slice-the-end-of-a-url-with-xslt-1-0

Обратите внимание:

  1. Шаблон iterUntil имеет три параметра:

    -- pCond -- функция (ссылка на шаблон), которая проверяет условие на текущий результат и потенциально выдает "сигнал остановки" (1).

    -- pFun -- функция (ссылка на шаблон), которая используется для получения следующего текущего результата из текущего результата (или изначально из входного аргумента $arg1).

    -- arg1 -- входной аргумент, на котором изначально применяется функция pFun.

  2. Наша функция pCond -- это шаблон, который соответствует my:condition. Она выдает "сигнал остановки" (выводит 1) только в том случае, если строка, переданная в качестве $arg1, не содержит символов '/'.

  3. Наша функция pFun является шаблоном, который соответствует my:skipSlash. Она отбрасывает все символы до первого '/' включительно в строке $arg1

  4. Начальный входной аргумент определен в $arg1 и является строковым значением, из которого должен быть получен только текст после последнего '/'.

  5. Основное преимущество использования FXSL заключается в том, что это избавляет от необходимости кодировать явную рекурсию и возможности ошибок при этом. Кроме того, шаблоны/функции являются очень общими и мощными и могут быть повторно использованы для решения огромных классов подобных задач.

2
ответ дан 7 December 2019 в 03:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: