XSLT - 将模板标记为斜体和粗体XML元素文本

时间:2015-04-08 20:42:51

标签: xml xslt tokenize

我在XSLT中实现了以下标记化模板。

<xsl:template match="sporting_arena/text()[normalize-space()]" name="split">
 <xsl:param name="pText" select="."/>
 <xsl:if test="normalize-space($pText)">
   <li>
     <xsl:call-template name="replace">
       <xsl:with-param name="pText" select="substring-before(concat($pText, ';'), ';')"/>
     </xsl:call-template>
   </li>
   <xsl:call-template name="split">
     <xsl:with-param name="pText" select="substring-after($pText, ';')"/>
   </xsl:call-template>
 </xsl:if>

<xsl:template name="replace">
   <xsl:param name="pText"/>
   <xsl:if test="normalize-space($pText)">
       <xsl:value-of select="substring-before(concat($pText, '*'),'*')"/>
       <xsl:if test="contains($pText, '*')">
           <br/>
         <xsl:call-template name="replace">
           <xsl:with-param name="pText" select="substring-after($pText, '*')"/>
         </xsl:call-template>
       </xsl:if>
    </xsl:if>
</xsl:template> 

我想知道是否可以添加到此标记化系统,使用相同的分隔符方法来粗体或斜体化我的XML元素文本中的某些单词,并在单词的每一边使用分隔符来表示粗体或斜体。

当前系统的XML示例:

        <sporting_arena>
    Adelaide Oval: An awesome new bike and truck that drove up* a hill and never came back.; 
The delimiter I choose here * places this text on a new line and now I'm;
On a new dot point. 
        </sporting_arena>

1 个答案:

答案 0 :(得分:3)

  

&#34;我想知道是否可以添加到此标记系统中   能够在我的XML元素文本中加粗或斜体化某些单词   使用相同的分隔符方法,在每一侧使用分隔符   单词表示粗体或斜体。&#34;

是的,有可能。此时,您应该能够自己实现这一点,使用与令牌化模板(您称之为&#34; split&#34;)所使用的原则相同的原则。创建标记为<li>的令牌与创建一个标记为<b><i>的令牌没有区别。


编辑:

回复:

  

&#34;我认为存在差异:将文本分区为li   元素,文本的每个片段最终都会在列表中结束   item和分隔符;标记列表项应该结束的位置   另一个立即开始。相反,粗体或斜体标记会   仅适用于开始和结束之间的文本部分   。定界符&#34;

所需的改变相当微不足道。请考虑以下示例:

<xsl:template name="italic">
    <xsl:param name="text"/>
    <xsl:param name="delimiter" select="'*'"/>
    <xsl:choose>
        <xsl:when test="contains($text, $delimiter) and contains(substring-after($text, $delimiter), $delimiter)">
            <xsl:value-of select="substring-before($text, $delimiter)"/>
            <i>
                <xsl:value-of select="substring-before(substring-after($text, $delimiter), $delimiter)"/>
            </i>
            <!-- recursive call -->
            <xsl:call-template name="italic">
                <xsl:with-param name="text" select="substring-after(substring-after($text, $delimiter), $delimiter)"/>
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="$text"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

当此模板被调用为:

<p>
    <xsl:call-template name="italic">
        <xsl:with-param name="text" select="input"/>
    </xsl:call-template>
</p>

输入为:

<input>Lorem ipsum *dolor* sit amet, *consectetuer* adipiscing * elit.</input>

结果将是:

<p>Lorem ipsum <i>dolor</i> sit amet, <i>consectetuer</i> adipiscing * elit.</p>

请注意,最后一个奇数分隔符按原样传递给输出。

您可以通过参数化要创建的令牌元素的名称来概括此模板以处理其他类型的标记(例如粗体)。

-
P.S。此解决方案自豪地使用xsl:choosexsl:choose是XSLT语言不可或缺的一部分,使用它充分利用它绝对没有错。它增加了代码的清晰度,而人工尝试避免使用它只会不必要地混淆代码。