4

PHP XSLTProcessor (XSLT 1.0) では EXSLT トークン化機能が利用できないようです。

純粋な XSL で実装しようとしましたが、動作させることができません:

<xsl:stylesheet
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:func="http://exslt.org/functions"
    xmlns:exsl="http://exslt.org/common"
    xmlns:my="http://mydomain.com/">

    <func:function name="my:tokenize">
        <xsl:param name="string"/>
        <xsl:param name="separator" select="'|'"/>
        <xsl:variable name="item" select="substring-before(concat($string,$separator),$separator)"/>
        <xsl:variable name="remainder" select="substring-after($string,$separator)"/>
        <xsl:variable name="tokens">
            <token><xsl:value-of select="$item"/></token>
            <xsl:if test="$remainder!=''">
                <xsl:copy-of select="my:tokenize($remainder,$separator)"/>
            </xsl:if>
        </xsl:variable>
        <func:result select="exsl:node-set($tokens)"/>
    </func:function>

    <xsl:template match="/">
        <xsl:copy-of select="my:tokenize('a|b|c')"/>
    </xsl:template>

</xsl:stylesheet>

期待される結果 :

    <token>a</token><token>b</token><token>c</token>

実結果 :

    abc

この質問が何度も投稿されていることは知っていますが、簡単な解決策が見つかりません。

ご協力ありがとうございました。

4

3 に答える 3

7

http://www.exslt.org/str/functions/tokenize/index.htmlを引用

次の XSLT プロセッサは、str:tokenize をサポートしています。

  • 4Suite の 4XSLT。(バージョン 0.12.0a3)
  • Daniel Veillardらのlibxslt。(バージョン 1.0.19)

PHP は libxslttokenizeを使用するため、利用可能であることを意味しますが、適切な拡張名前空間を使用する必要があります (これは使用しません)。

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:str="http://exslt.org/strings"
    extension-element-prefixes="str"
    …

次に、トークン化を関数として使用できます。たとえば、1 ~ 12 の数字で選択ボックスを作成できます。

<select name="months">
    <xsl:for-each select="str:tokenize('1,2,3,4,5,6,7,8,9,10,11,12', ',')">
        <xsl:element name="option">
            <xsl:attribute name="value">
                <xsl:value-of select="."/>
            </xsl:attribute>
            <xsl:value-of select="."/>
        </xsl:element>
    </xsl:for-each>
</select>
于 2012-05-04T10:56:39.703 に答える
2

私は関数を使用していないので少し時代遅れかもしれませんが、tokenize特別な拡張機能なしで必要なことを行う次のテンプレートがあります。

<xsl:template name="tokenize">
  <xsl:param name="string"/>
  <xsl:param name="separator" select="'|'"/>

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

次のように呼び出され、目的の出力が得られるはずです。

<xsl:call-template name="tokenize">
  <xsl:with-param name="string" select="'a|b|c'"/>
</xsl:call-template>
于 2012-05-04T11:48:59.307 に答える
0

独自の実装を作成する必要はありません。さらに強力な機能を提供する既存のFXSL str-split-to-wordsテンプレートを使用するだけです。

を使用した短いデモを次に示しますstr-split-to-words

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common">

   <xsl:import href="strSplit-to-Words.xsl"/>
   <xsl:output indent="yes" omit-xml-declaration="yes"/>

    <xsl:template match="/">
      <xsl:variable name="vwordNodes">
        <xsl:call-template name="str-split-to-words">
          <xsl:with-param name="pStr" select="/"/>
          <xsl:with-param name="pDelimiters" 
                          select="', &#9;&#10;&#13;'"/>
        </xsl:call-template>
      </xsl:variable>

      <xsl:apply-templates select="ext:node-set($vwordNodes)/*"/>
    </xsl:template>

    <xsl:template match="word">
      <xsl:value-of select="concat(position(), ' ', ., '&#10;')"/>
    </xsl:template>
</xsl:stylesheet>

この変換が次の XML ドキュメントに適用された場合:

<t>out, of
 luck</t>

必要な結果が生成されます。つまり、すべての単語とその位置のシーケンスです

pDelimitersパラメータで指定された隣接する区切り文字の最大長シーケンスが区切り文字として使用されることに注意してください。

1 out
2 of
3 luck
于 2012-05-04T12:18:57.127 に答える