xsl:如何拆分字符串?

Jas*_*n S 33 xml xslt xslt-2.0 xslt-1.0

我想将分号(;)上的地址拆分为由<br />以下各项分隔的行:

例如if address= 123 Elm Street,我想输出123 Elm Street,

但如果address= 123 Elm Street;PO Box 222,我想输出

123 Elm Street<br />PO Box 222
Run Code Online (Sandbox Code Playgroud)

如果address= 123 Elm Street;PO Box 222;c/o James Jones,我想输出

123 Elm Street<br />PO Box 222<br />c/o James Jones
Run Code Online (Sandbox Code Playgroud)

有没有办法做到这一点?(可能很简单,但我不熟悉XSLT)

普通的XSL选择器是

<xsl:value-of select="address"/>
Run Code Online (Sandbox Code Playgroud)

我想修改这个XSLT片段以分号分割.


更新:显然,答案涉及使用<xsl:call-template>和功能substring-before()substring-after().

但我是XSLT的初学者,我真的可以使用一些帮助来解决这个问题.

Dim*_*hev 63

I.普通XSLT 1.0解决方案:

这种转变:

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

 <xsl:template match="text()" name="split">
  <xsl:param name="pText" select="."/>
  <xsl:if test="string-length($pText)">
   <xsl:if test="not($pText=.)">
    <br />
   </xsl:if>
   <xsl:value-of select=
    "substring-before(concat($pText,';'),';')"/>
   <xsl:call-template name="split">
    <xsl:with-param name="pText" select=
     "substring-after($pText, ';')"/>
   </xsl:call-template>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

应用于此XML文档时:

<t>123 Elm Street;PO Box 222;c/o James Jones</t>
Run Code Online (Sandbox Code Playgroud)

产生想要的,更正的结果:

123 Elm Street<br />PO Box 222<br />c/o James Jones
Run Code Online (Sandbox Code Playgroud)

II.FXSL 1(适用于XSLT 1.0):

这里我们只使用FXSL模板str-map(并且不必在第999次写入递归模板):

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://fxsl.sf.net/"
xmlns:testmap="testmap"
exclude-result-prefixes="xsl f testmap"
>
   <xsl:import href="str-dvc-map.xsl"/>

   <testmap:testmap/>

   <xsl:output omit-xml-declaration="yes" indent="yes"/>

   <xsl:template match="/">
     <xsl:variable name="vTestMap" select="document('')/*/testmap:*[1]"/>
     <xsl:call-template name="str-map">
       <xsl:with-param name="pFun" select="$vTestMap"/>
       <xsl:with-param name="pStr" select=
       "'123 Elm Street;PO Box 222;c/o James Jones'"/>
     </xsl:call-template>
   </xsl:template>

    <xsl:template name="replace" mode="f:FXSL"
         match="*[namespace-uri() = 'testmap']">
      <xsl:param name="arg1"/>

      <xsl:choose>
       <xsl:when test="not($arg1=';')">
        <xsl:value-of select="$arg1"/>
       </xsl:when>
       <xsl:otherwise><br /></xsl:otherwise>
      </xsl:choose>
    </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

当此转换应用于任何XML文档(未使用)时,会产生相同的,想要的正确结果:

123 Elm Street<br/>PO Box 222<br/>c/o James Jones
Run Code Online (Sandbox Code Playgroud)

III.使用XSLT 2.0

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

 <xsl:template match="text()">
  <xsl:for-each select="tokenize(.,';')">
   <xsl:sequence select="."/>
   <xsl:if test="not(position() eq last())"><br /></xsl:if>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

当此转换应用于此XML文档时:

<t>123 Elm Street;PO Box 222;c/o James Jones</t>
Run Code Online (Sandbox Code Playgroud)

产生了想要的正确结果:

123 Elm Street<br />PO Box 222<br />c/o James Jones
Run Code Online (Sandbox Code Playgroud)

  • @Jason-S:XSLT(和XPath中)的`.`表示当前节点(上下文节点).`not($ pText =.)`是`true()`如果参数`$ pText`的字符串值不等于当前节点的字符串值 - 我们只想输出'<br />`在这种情况下,否则我们的输出将以"<br />"开头 (3认同)

Mor*_*gil 5

如果您的 XSLT 处理器支持EXSLT,您可以使用str:tokenize,否则,该链接包含使用 substring-before 等函数的实现。

  • @Jason S - 在这种情况下,你不能依赖它,你需要自己提供该函数;该实现可在链接的http://exslt.org/str/functions/tokenize/str.tokenize.template.xsl中找到 (2认同)