我对XSL,XPATH等还很陌生。一些代码是我的,有些是别人的。
问题::当下面的模板与我在下面进一步概述的模板一起调用时,if测试之后的所有xsl:text
节点都将输出为字符串而不是HTML节点,因此不会呈现图标。
这个问题与理解为什么?发生了什么有关。我的确切问题在这篇文章的底部。
因此,我有一个模板,该模板可生成带有<use>
元素的SVG元素,以与SVG精灵一起使用。
<xsl:template name="svg-link">
<xsl:param name="svg-id"/>
<xsl:param name="svg-class"/>
<xsl:param name="svg-title"/>
<span class="{$svg-class} svgstore svgstore--{$svg-loc}">
<svg>
<xsl:if test="$svg-title != ''">
<title><xsl:value-of select="$svg-title"/></title>
</xsl:if>
<xsl:text disable-output-escaping="yes"><use xlink:href="</xsl:text>
<xsl:value-of select="concat('#', $svg-loc)" />
<xsl:text disable-output-escaping="yes">"></use></xsl:text>
</svg>
</span>
</xsl:template>
各种模板都调用/应用此模板。我特别有一个问题。我们有两个由CMS实施的代码段,它们输出相同的标记,但是这些代码段的配置实施方式不同,即页面模板A与页面模板B。所涉及的代码段由多个XSL模板组成。模板的组织方式如下:
这是上面演示的一些简化的伪代码:
<xsl:template name="snippet">
<xsl:param name="outer-classes"/>
<xsl:param name="inner-classes"/>
<xsl:variable name="items">
<xsl:call-template name="snippet-model"/>
</xsl:variable>
<!-- Render Snippet if it has content. -->
<xsl:if test="count( $items )">
<div class="{ $outer-classes }">
<div class="{ $inner-classes }">
<xsl:copy-of select="$items">
</div>
</div>
</xsl:if>
</xsl:template>
<!-- Placeholder. Defined by each page template. -->
<xsl:template name="snippet-model"/>
<xsl:template name="snippet-item">
<xsl:param name="a"/>
<xsl:param name="b"/>
<xsl:param name="b"/>
<div class="snippet-item {$a}">
<xsl:apply-templates select="$b"/>
<xsl:call-template name="svg-link">
<xsl:with-param name="svg-id">alpha</xsl:with-param>
<xsl:with-param name="svg-class">alpha</xsl:with-param>
<xsl:with-param name="svg-title">The Title</xsl:with-param>
</xsl:call-template>
</div>
</xsl:template>
以及页面模板如何使用上述内容的示例:
<xsl:template match="table[@class = 'snippet-alpha']">
<xsl:call-template="snippet">
<xsl:with-param name="outer-classes">page-template-a other</xsl:with-param>
<xsl:with-param name="inner-classes">some-template-modifier</xsl:with-param>
</xsl:call-template>
</xsl:template>
<!-- Template definition of `snippet-model` template. -->
<xsl:template name="snippet-model">
<!-- Another page template might not use `tbody/tr` to loop over. -->
<xsl:for-each select="tbody/tr">
<xsl:call-template="snippet-item">
<xsl:with-param name="a" select="td[1]"/>
<xsl:with-param name="b" select="td[2]"/>
<xsl:with-param name="c" select="td[3]"/>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
我已将问题范围缩小为xsl:variable
捕获xsl:call-template
模板中snippet
的结果。和/或稍后使用xsl:copy-of
对该变量进行引用。
在下面,我有工作和非工作解决方案,但我都没有完全理解为什么它们可能起作用或不起作用。
xmlns:xlink="http://www.w3.org/1999/xlink"
模板的文件向xsl:stylesheet
添加svg-link
,然后修改svg-link
模板,请参见下面的代码清单。 xsl:variable
的值,该值用xsl:call-template
捕获xsl:copy-of
的结果。我用另一个xsl:copy-of
替换了xsl:call-template
,该变量与在变量内进行的调用相同。xsl:sequence
代替了xsl:copy-of
。xsl:variable
属性捕获xsl:call-template
结果的as
数据类型(?)。即as="node()*"
。<xsl:template name="svg-link">
<xsl:param name="svg-id"/>
<xsl:param name="svg-class"/>
<xsl:param name="svg-title"/>
<span class="{$svg-class} svgstore svgstore--{$svg-loc}">
<svg>
<xsl:if test="$svg-title != ''">
<title><xsl:value-of select="$svg-title"/></title>
</xsl:if>
<use xlink:href="{concat( '#', $svg-loc )}"></use>
</svg>
</span>
</xsl:template>
问题:为什么基于调用svg-link
的结果,xsl:call-template
模板的某些内容作为字符串(而不是HTML)输出为字符串(而不是HTML)被捕获/被呼叫?如您所见,我有有效的和无效的解决方案-我想知道为什么。谢谢!
答案 0 :(得分:1)
首先,disable-output-escaping
是可选的序列化功能。此外,当XSLT 2或3规格根本无法使用时,它们会列出来,请参阅https://www.w3.org/TR/xslt-30/#disable-output-escaping
如果为
xsl:value-of
或xsl:text
禁用了输出转义 指令在临时输出状态有效时进行评估, 禁用输出转义的请求将被忽略。
和https://www.w3.org/TR/xslt-30/#dt-temporary-output-state
xsl:变量,xsl:param,xsl:with-param,xsl:function,xsl:key, xsl:sort,xsl:accumulator-rule和xsl:merge-key始终会评估 临时包含在其包含的序列构造函数中的指令 输出状态
因此在您的xsl:variable
内,任何disable-output-escaping
都无法工作。
完全不需要使用它来构造SVG use
元素,您可以创建任何结果元素作为文字结果元素,例如<use xlink:href="{concat( '#', $svg-loc )}"></use>
(在该名称空间的属性范围内具有适当的XLink名称空间声明),或者,如果需要计算名称或名称空间的一部分,请使用xsl:element
。