как обрабатывать массив строк в файле «.xsl»?

#linux #xslt

#linux #xslt

Вопрос:

У меня есть массив строк в файле .xsl, теперь я должен использовать каждую строку, разделенную пробелами, по-разному. Как я могу получить строки?

У меня есть следующий массив строк:

 strarray="hw.oh.xml hg.hd.gnl th.ik.lkj"
  

Я должен получить «hw.oh.xml строки «», «hg.hd.gnl», «th.ik.lkj» отдельно, чтобы выполнить с ними какую-то операцию.

Как я могу это сделать?

Комментарии:

1. Хороший вопрос, 1. Смотрите мой ответ для трех полных решений. 🙂

2. Замечательно… Большое спасибо @ Dimitre Novatchev за ваши ответы. Но в моем случае у меня есть переменная, которая содержит, как я показал в моей проблеме. тогда как с этим справиться. и он содержит более 10 строк. Заранее спасибо .. я использую версию = «1.0» xslt.

3. Добро пожаловать. Особенно в вашем случае, я добавил четвертое решение к своему ответу.

Ответ №1:

Есть много способов сделать это:

I. Использование XPath substring-before() и substring-after() функций:

 <xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:variable name="vStrArray" select="'hw.oh.xml hg.hd.gnl th.ik.lkj'"/>

 <xsl:template match="/">
  <xsl:value-of select="substring-before($vStrArray, ' ')"/>
  <xsl:text>amp;#xA;</xsl:text>

  <xsl:value-of select="substring-before(substring-after($vStrArray, ' '),' ')"/>
  <xsl:text>amp;#xA;</xsl:text>
  <xsl:value-of select="substring-after(substring-after($vStrArray, ' '),' ')"/>
  <xsl:text>amp;#xA;</xsl:text>
 </xsl:template>
</xsl:stylesheet>
  

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

 hw.oh.xml
hg.hd.gnl
th.ik.lkj
  

Этот метод может быстро стать чрезмерно сложным и не рекомендуется, за исключением «массивов», состоящих всего из 2-3 элементов.

II. Представление «массива» в виде XML-документа в XSLT 1.0:

 <xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <my:array>
  <item>hw.oh.xml</item>
  <item>hg.hd.gnl</item>
  <item>th.ik.lkj</item>
 </my:array>

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

 <xsl:template match="/">
  <xsl:value-of select="$vStrArray[1]"/>
  <xsl:text>amp;#xA;</xsl:text>

  <xsl:value-of select="$vStrArray[2]"/>
  <xsl:text>amp;#xA;</xsl:text>
  <xsl:value-of select="$vStrArray[3]"/>
  <xsl:text>amp;#xA;</xsl:text>
 </xsl:template>
</xsl:stylesheet>
  

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

 hw.oh.xml
hg.hd.gnl
th.ik.lkj
  

Я рекомендую этот метод представления «массива» — для приложений XSLT 1.0.

III. XSLT 2.0 / XPath 2.0

Просто используйте последовательность строк:

 <xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:variable name="vStrArray"
      select="'hw.oh.xml', 'hg.hd.gnl', 'th.ik.lkj'"/>

 <xsl:template match="/">
  <xsl:sequence select=
   "for $i in 1 to count($vStrArray)
     return
        concat($vStrArray[$i], 'amp;#xA;')
   "/>
 </xsl:template>
</xsl:stylesheet>
  

Результат:

  hw.oh.xml
 hg.hd.gnl
 th.ik.lkj
  

ОБНОВЛЕНИЕ: Оператор прокомментировал, что он застрял с начальным представлением разделенных пробелами значений, содержащихся в одной строке.

IV. Преобразуйте строку значений, разделенных пробелом, в XML-фрагмент для удобства использования.

 <xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

    <xsl:variable name="vStrArray" select="'hw.oh.xml hg.hd.gnl th.ik.lkj'"/>

    <xsl:variable name="vrtfDoc">
      <xsl:call-template name="makeIndex">
        <xsl:with-param name="pText" select="$vStrArray"/>
      </xsl:call-template>
    </xsl:variable>

    <xsl:variable name="vStrIndex" select="ext:node-set($vrtfDoc)/*"/>

    <xsl:template match="/">
        <xsl:value-of select="$vStrIndex[1]"/>
        <xsl:text>amp;#xA;</xsl:text>
        <xsl:value-of select="$vStrIndex[2]"/>
        <xsl:text>amp;#xA;</xsl:text>
        <xsl:value-of select="$vStrIndex[3]"/>
    </xsl:template>

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

     <xsl:if test="string-length($pText)>0">
      <item>
       <xsl:value-of select=
         "substring-before(concat($pText,' '), ' ')"/>
      </item>
      <xsl:call-template name="makeIndex">
       <xsl:with-param name="pText" select=
       "substring-after($pText,' ')"/>
      </xsl:call-template>
     </xsl:if>
    </xsl:template>
</xsl:stylesheet>
  

Это преобразование создает XML-фрагмент из строки, в котором каждый <item> элемент содержит только одно из строковых значений. Тогда его использование такое же, как если бы это был массив.