2011-01-30 43 views
26

我想将分号(;)上的地址分隔成由<br />分隔的行:xsl:如何拆分字符串?

例如,如果address = 123 Elm Street,我要输出123 Elm Street

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

123 Elm Street<br />PO Box 222 

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

123 Elm Street<br />PO Box 222<br />c/o James Jones 

是有办法做到这一点? (可能很容易,但我没那么熟悉XSLT)

平原XSL选择是

<xsl:value-of select="address"/> 

,我想修改该XSLT片段分割上分号。


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

但我是XSLT的初学者,我真的可以使用一些帮助来做到这一点。

+0

可能重复有一个Split()函数?](http://stackoverflow.com/questions/136500/does-xslt-have-a-split-function ) – porges 2011-01-30 21:32:13

+0

也许它是一个近似重复的,但我不知道如何应用这个问题的答案,我的问题。 – 2011-01-30 21:35:01

+0

另请参阅http://stackoverflow.com/questions/10750184/looping-through-multiple-sequences-from-strtokenize – Vadzim 2016-12-09 09:27:37

回答

52

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> 

当此XML文档上施加:

<t>123 Elm Street;PO Box 222;c/o James Jones</t> 

产生想要的,校正结果

123 Elm Street<br />PO Box 222<br />c/o James Jones 

二, 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> 

当这一转变施加在任何XML文档(未使用),同样的,希望正确的结果产生

123 Elm Street<br/>PO Box 222<br/>c/o James Jones 

三,使用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> 

当这一转型是这个XML文档施加:

<t>123 Elm Street;PO Box 222;c/o James Jones</t> 

想要的,正确的结果产生:不XSLT的

123 Elm Street<br />PO Box 222<br />c/o James Jones 
1

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