是否可以找到用连字符分隔的单词并用一些标签包围它们?
输入
<root>
text text text-with-hyphen text text
</root>
所需输出
<outroot>
text text <sometag>text-with-hyphen</sometag> text text
</outroot>
这个 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="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root/text()">
<xsl:analyze-string select="." regex="([^ ]*\-[^ ]*)+">
<xsl:matching-substring>
<sometag><xsl:value-of select="."/></sometag>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
</xsl:stylesheet>
应用于提供的 XML 文档时:
<root>
text text text-with-hyphen text text
</root>
产生想要的正确结果:
<root>
text text <sometag>text-with-hyphen</sometag> text text
</root>
说明:
正确使用 XSLT 2.0<xsl:analyze-string>
指令及其允许的子指令。
刚刚检查,它工作。所以背后的想法是在整个文本上创建递归迭代。并在递归步骤中使用 XPath 函数contains
检测单词(参见 的用法$word
)是否包含连字符:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/root">
<outroot>
<xsl:call-template name="split-by-space">
<xsl:with-param name="str" select="text()"/>
</xsl:call-template>
</outroot>
</xsl:template>
<xsl:template name="split-by-space"> <!-- mode allows distinguish another tag 'step'-->
<xsl:param name="str"/>
<xsl:if test="string-length($str)"><!-- declare condition of recursion exit-->
<xsl:variable name="word"> <!-- select next word -->
<xsl:value-of select="substring-before($str, ' ')"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="contains($word, '-')"> <!-- when word contains hyphen -->
<sometag>
<xsl:value-of select='concat(" ", $word)'/><!-- need add space-->
</sometag>
</xsl:when>
<xsl:otherwise>
<!-- produce normal output -->
<xsl:value-of select='concat(" ", $word)'/><!-- need add space-->
</xsl:otherwise>
</xsl:choose>
<!-- enter to recursion to proceed rest of str-->
<xsl:call-template name="split-by-space">
<xsl:with-param name="str"><xsl:value-of select="substring-after($str, ' ')"/></xsl:with-param>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>