XSLT 2.0: разбить строку на значения, разделенные запятыми - PullRequest
1 голос
/ 06 января 2012

Я новичок в XSLT и у меня есть требование, в котором я должен манипулировать строкой, как показано ниже.

Входная строка = "12345"

Ожидаемый результат = "12345,1234,123,12"

Может кто-нибудь помочь мне добиться этого в XSLT 2.0

Ответы [ 4 ]

1 голос
/ 06 января 2012

Вот более эффективное решение, чем принятое в настоящее время, которое не использует функцию reverse() :

<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:output method="text"/>

 <xsl:function name="my:subSequences" as="xs:string*">
   <xsl:param name="pString" as="xs:string"/>
   <xsl:param name="pstartLength" as="xs:integer"/>
   <xsl:sequence select=
     "for $totalLength in string-length($pString),
          $length in 1 to $totalLength -$pstartLength +1,
          $revLength in $totalLength -$length +1
               return
                  substring($pString, 1, $revLength)"/>
 </xsl:function>

 <xsl:template match="/">
  <xsl:value-of select="my:subSequences('12345', 2)" separator=","/>
 </xsl:template>
</xsl:stylesheet>

Когда выполняется это преобразование, получается нужный, правильный результат :

12345,1234,123,12

Объяснение :

Спецификация XPath 2.0 W3C определяет, что если первый аргумент оператора to больше второго аргумента, то результирующая последовательность будет пустой последовательностью.

Все еще можно обойти это ограничение и построить убывающую целочисленную последовательность, например:

 for $k in 0  to $big - $small
  return  
     $big - $k

Использование такого выражения более эффективно, особенно для больших последовательностей, чем сначала создание возрастающей последовательности, а затем ее обращение с помощью функции reverse().

1 голос
/ 06 января 2012

Вот некоторые подходы XSLT / XPath 2.0:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:mf="http://example.com/mf"
  exclude-result-prefixes="xs mf"
  version="2.0">

  <xsl:function name="mf:sub-sequences" as="xs:string*">
    <xsl:param name="input" as="xs:string"/>
    <xsl:param name="min-length" as="xs:integer"/>
    <xsl:sequence select="reverse(
                            for $length in $min-length to string-length($input)
                            return substring($input, 1, $length)
                          )"/>
  </xsl:function>

  <xsl:template name="main">
    <xsl:variable name="s" select="'12345'"/>
    <xsl:value-of select="mf:sub-sequences($s, 2)" separator=","/>
  </xsl:template>

</xsl:stylesheet>
1 голос
/ 06 января 2012

Это должно сработать:

<xsl:template match="/">
  <xsl:call-template name="minus-one">
    <xsl:with-param name="input" select="'12345'"/>
  </xsl:call-template>
</xsl:template>

<xsl:template name="minus-one">
  <xsl:param name="input"/>

  <xsl:value-of select="$input"/>

  <xsl:if test="string-length($input) gt 2"><xsl:text>,</xsl:text>
    <xsl:call-template name="minus-one">
      <xsl:with-param name="input" select="substring($input, 1, string-length($input) - 1)"/>
    </xsl:call-template>
  </xsl:if>
</xsl:template>
0 голосов
/ 06 января 2012

на

<string>12345</string>

следующий xslt выдаст результат 12345,1234,123,12

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>

    <xsl:template match="string">
        <xsl:call-template name="doTheFunkeyMonkey">
            <xsl:with-param name="data" select="."/>
        </xsl:call-template>
    </xsl:template>

    <xsl:template name="doTheFunkeyMonkey">
        <xsl:param name="data"/>
        <xsl:value-of select="$data"/>
        <xsl:if test="string-length($data) &gt; 2">
            <xsl:text>,</xsl:text>
            <xsl:call-template name="doTheFunkeyMonkey">
                <xsl:with-param name="data" select="substring($data,1,string-length($data)-1)"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>
...