xsl:如何拆分字符串?

问题描述 投票:0回答:3

我想将分号 (

;
) 上的地址拆分为由
<br />
:

分隔的行

例如如果

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 的初学者,我真的需要一些帮助才能做到这一点。

xml xslt xslt-1.0 xslt-2.0
3个回答
69
投票

我。普通 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>

产生了想要的、正确的结果

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

5
投票

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


0
投票

使用 XSLT 2.0,您可以使用

xsl:analyse-string
完成此任务:

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

  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="text()">
    <xsl:analyze-string select="." regex=";">
      <xsl:matching-substring>
        <br/>
      </xsl:matching-substring>
      <xsl:non-matching-substring>
        <xsl:value-of select="."/>
      </xsl:non-matching-substring>
    </xsl:analyze-string>
  </xsl:template>

</xsl:stylesheet>

以下XML

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

然后将转换为:

<root>
   <address>123 Elm Street</address>
   <address>123 Elm Street<br/>PO Box 222</address>
   <address>123 Elm Street<br/>PO Box 222<br/>c/o James Jones</address>
</root>
© www.soinside.com 2019 - 2024. All rights reserved.