我想将分号 (
;
) 上的地址拆分为由 <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 的初学者,我真的需要一些帮助才能做到这一点。
我。普通 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
如果您的 XSLT 处理器支持 EXSLT,您可以使用 str:tokenize,否则,链接包含使用 substring-before 等函数的实现。
使用 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>