我正在尝试从参数中选择一些文本并将其放入变量中,此变量只有纯文本。
<xsl:variable name="Underline">
<xsl:choose>
<xsl:when test="contains($style-name, 'u')">true</xsl:when>
</xsl:choose>
</xsl:variable>
此参数( $ style-name )的值可以是 strike,em,u,strong,sub和sup。 的任何内容。 p>
$style-name: "strike em u sub"
问题是,当我使用上面的代码时,它还认为 sub 和 u 是相同的,因为它找到了字符u。这是包含的本质。
我在这里做了一些研究:
XPath to return only elements containing the text, and not its parents
但我找不到任何适合我的东西。如果您需要更多信息,请与我们联系。
这也只是XSLT 1.0。我正在使用Visual Studio 2012,我不是100%确定引擎是什么。
我可以提供输入,但它超出了问题的范围,只是一个子问题。
答案 0 :(得分:4)
XSLT 2.0解决方案
分成一系列令牌并使用=
进行比较:
<xsl:when test="tokenize($style-name,' ') = 'u')">true</xsl:when>
这会将所有以空格分隔的标记转换为序列,如果任何标记与“u”匹配,= 'u'
将匹配。
XSLT 1.1解决方案
<xsl:template name="tokenize">
<xsl:param name="token" />
<xsl:param name="text"/>
<xsl:if test="string-length($text)">
<token><xsl:value-of select="substring-before(concat($text,$token),$token)"/></token>
<xsl:call-template name="tokenize">
<xsl:with-param name="text" select="substring-after($text,$token)"/>
<xsl:with-param name="token" select="$token"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
...
<xsl:variable name="tokens">
<xsl:call-template name="tokenize">
<xsl:with-param name="text" select="$style-name"/>
<xsl:with-param name="token" select="' '"/>
</xsl:call-template>
</xsl:variable>
<xsl:when test="$tokens/token = 'u'">true</xsl:when>
XSLT 1.0解决方案
需要包含在每个主要XSL处理器(包括MSXSL)中的扩展。将此命名空间声明添加到样式表:
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
并更改@test:
<xsl:when test="msxsl:node-set($tokens)/token = 'u'">true</xsl:when>
对于支持ESLT的处理器(Saxon,xsltproc,Xalan-J,jd.xslt和4XSLT),请使用xmlns:exsl="http://exslt.org/common"
和exsl:node-set()
。对于Xalan-C,请使用xmlns:xalan="http://xml.apache.org/xalan"
和xalan:nodeset()
。
答案 1 :(得分:4)
这实际上不需要标记化。应该这么简单:
<xsl:variable name="Underline">
<xsl:if test="contains(concat(' ',$style-name,' '),' u ')">true</xsl:if>
</xsl:variable>
或者甚至更好
<xsl:variable name="Underline">
<xsl:if test="contains(concat(' ',normalize-space($style-name),' '),' u ')">true</xsl:if>
</xsl:variable>
也就是说,如果确保您有一个以空格分隔的列表。