2012-06-21 3 views
1

Используя XSL 1.0, я нашел хорошую функцию tokenize. Теперь мне нужно для каждого по итоговым жетонам. Я очень новичок в XSL.XSL 1.0 - Как использовать для каждого по токенизированной строке

РНР эквивалент того, что мне нужно:

$in = 'a,b,c,d'; 
$tokens = explode (',', $in); 
foreach ($tokens as $token) { 
    echo $token; 
} 

Вот что я до сих пор. Эта строка будет выводиться «а, б, в, d'-

<xsl:value-of select="@CommaSeparated" /> 

Это запустит эту строку через разметить функции-

<xsl:call-template name="tokenize"> 
    <xsl:with-param name="pText" select="@CommaSeparated"/> 
    </xsl:call-template> 

и функция разметить. Я понимаю, что это делает, просто не формат данных, которые он выкладывает

для улицы
<xsl:template name="tokenize"> 
    <xsl:param name="pText"/> 

    <xsl:if test="string-length($pText)"> 
    <tag> 
     <xsl:value-of select= 
     "substring-before($pText, ',')"/> 
    </tag> 

    <xsl:call-template name="tokenize"> 
     <xsl:with-param name="pText" select= 
     "substring-after($pText, ',')"/> 
    </xsl:call-template> 
    </xsl:if> 
</xsl:template> 
+0

Так Каков ваш вопрос? –

+0

Вы спрашиваете, поддерживает ли XSLT для каждого? Да, это так - 'xsl: for-each', thoguh лучше избегать использования шаблона, где это возможно. – Utkanos

+0

Для записи, что я закончил делать, написать несколько Tokenize-подобных функций, которые будут делать разделение и вывод. Таким образом, шаблон «Tokenize_Links» будет принимать «a, b, c» и « a, b и т. Д.». – user1472408

ответ

3

Во-первых, функция разметить используется не на самом деле правильно. Теоретически, он должен выплюнуть список тегов элементов (строго говоря, «фрагмент дерева результата»), как так

<tag>a</tag> 
<tag>b</tag> 
<tag>c</tag> 
<tag>d</tag> 

Но это на самом деле хватает последнего элемента

<tag>a</tag> 
<tag>b</tag> 
<tag>c</tag> 
<tag></tag> 

You вероятно, лучше найти другую функцию tokenize здесь (в StackOverflow обязательно должны быть рабочие).

Но, в ответ на ваш вопрос об использовании XSL: для каждого-за этого, вы могли бы попытаться сделать что-то вроде этого ...

<xsl:variable name="tags"> 
    <xsl:call-template name="tokenize"> 
     <xsl:with-param name="pText" select="@CommaSeparated"/> 
    </xsl:call-template> 
    </xsl:variable> 

    <xsl:for-each select="$tags/tag"> 
    <xsl:copy-of select="." /> 
    </xsl:for-each> 

То есть, хранить список тегов в переменную, а затем петлю над ними. Однако, если вы попробуете это в XSLT1.0, вы получите сообщение об ошибке «Выражение должно оцениваться с помощью набора узлов». Чтобы обойти это, вам нужно использовать функцию расширения. EXSLT, вероятно, самый распространенный. Вы бы заявить об этом в вашем XSLT как так

<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:exsl="http://exslt.org/common" 
    exclude-result-prefixes="exsl"> 

Вы можете их просто изменить XSL: в обмен на каждого следующим образом:

<xsl:for-each select="exsl:node-set($tags)/tag"> 

Таким образом, учитывая следующие XML

<a CommaSeparated="a,b,c,d"></a> 

И следующие XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common" exclude-result-prefixes="exsl"> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="/a"> 
     <xsl:variable name="tags"> 
      <xsl:call-template name="tokenize"> 
       <xsl:with-param name="pText" select="@CommaSeparated"/> 
      </xsl:call-template> 
     </xsl:variable> 
     <xsl:for-each select="exsl:node-set($tags)/tag"> 
      <xsl:copy-of select="."/> 
     </xsl:for-each> 
    </xsl:template> 

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

Ниже выводится (с последним тэгом пустым из-за прослушивают разметить функции вы используете)

<tag>a</tag> 
<tag>b</tag> 
<tag>c</tag> 
<tag></tag> 
+0

Спасибо Тим. К сожалению, эта дефектная функция Tokenize является той, которую я нашел в StackOverflow. – user1472408

+0

Посмотрите на этот вопрос, который задает более или менее одно и то же, и имеет функцию tokenize, которая работает! http://stackoverflow.com/questions/7425071/split-function-in-xslt-1-0 –

0

Проверьте этот код:

<xsl:variable name="val"> 
     <xsl:value-of select="@CommaSeparated"/><xsl:text disable-output-escaping="yes"><![CDATA[ ]]></xsl:text> 
</xsl:variable> 

<xsl:template match="/a"> 
    <xsl:variable name="tags"> 
     <xsl:call-template name="tokenize"> 
      <xsl:with-param name="pText" select="$val"/> 
     </xsl:call-template> 
    </xsl:variable> 
    <xsl:for-each select="exsl:node-set($tags)/tag"> 
     <xsl:copy-of select="."/> 
    </xsl:for-each> 
</xsl:template> 

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

+0

Вступительное замечание «Проверить этот код» может задавать вопрос, или это можно сказать вот пример. Если это вопрос, то это не должно быть написано как ответ. Если это действительно ответ, тогда было бы полезно сказать это, а также объяснить, как он решает исходный вопрос. – AdrianHHH

Смежные вопросы