如何用连字符查找单词?

时间:2012-06-13 13:05:07

标签: xslt xslt-2.0

是否可以找到用连字符分隔的单词并用一些标记包围它们?

输入

<root>
    text text text-with-hyphen text text    
</root>

必需的输出

<outroot>
    text text <sometag>text-with-hyphen</sometag> text text
</outroot>

2 个答案:

答案 0 :(得分:3)

此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> 指令及其允许的子指令。

答案 1 :(得分:2)

刚检查过,它有效。因此,背后的想法是在整个文本上创建递归迭代。在使用XPath函数contains的内部递归步骤中,检测word(请参阅$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>