首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >问题: SVG <use>元素在XSL模板中转换为字符串。

问题: SVG <use>元素在XSL模板中转换为字符串。
EN

Stack Overflow用户
提问于 2019-05-03 15:05:08
回答 1查看 180关注 0票数 1

我对XSL、XPATH等都很陌生,有些代码是我的,有些是别人的。

问题:当下面的模板与我在下面描述的模板一起被调用时,if测试之后的所有xsl:text节点都被输出为一个字符串而不是一个xsl:text节点,因此图标不会被呈现。

这个问题与理解为什么有关?是怎么回事。我的确切问题是在这篇文章的末尾。

因此,我有一个模板,我调用它生成带有<use>元素的SVG元素,以便与sprite一起使用。

代码语言:javascript
复制
<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">&lt;use xlink:href="</xsl:text>
      <xsl:value-of select="concat('#', $svg-loc)" />
      <xsl:text disable-output-escaping="yes">"&gt;&lt;/use&gt;</xsl:text>
    </svg>
  </span>

</xsl:template>

所有类型的模板都调用/应用此模板。有一个特别的,我有一个问题。我们有两个由CMS实现的片段,它们输出相同的标记,但是代码段的配置实现方式不同,即页面模板A和页面模板B。模板的组织方式如下:

  • 片段模板:用于所有调用者的代码片段的入口点。接受几个与CSS类相关的参数。为代码段创建一些包装器元素。调用以下模板。
  • “模型”模板:是一个需要由每个页面模板定义的模板。如上所述,每个页面模板使用不同的方法来实现代码段的配置选项。这样做的目的是让下面的模板不知道代码片段是如何配置的,因为这个模板负责了解这些细节并将其传递给下面的模板。
  • 片段项模板:根据“模型”模板传递给它的信息呈现片段的大部分标记。

下面是上面演示的一些简化伪代码:

代码语言:javascript
复制
<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>

以及页面模板如何使用上述内容的示例:

代码语言:javascript
复制
<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:variablesnippet模板中捕获xsl:call-template的结果。和/或稍后使用xsl:copy-of引用该变量。

我试过什么?

下面我有工作的和非工作的解决方案,所有这些我都不完全摸索为什么他们可以或不可能工作。

  • 工作:为包含svg-link模板的文件向xsl:stylesheet添加xmlns:xlink="http://www.w3.org/1999/xlink",然后对svg-link模板进行修改,请参阅下面的代码列表。
  • 工作:,而不是输出用xsl:copy-of捕获xsl:call-template结果的xsl:variable的值。我将xsl:copy-of替换为与变量内部调用相同的第二个xsl:call-template
  • 不起作用:使用xsl:sequence而不是xsl:copy-of
  • 不起作用:尝试了数据类型(?)用xsl:variable属性捕获xsl:call-template的结果的as。即as="node()*".
代码语言:javascript
复制
<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>

问题:为什么根据如何捕获/调用对xsl:call-template的调用结果,将svg-link模板的某些内容输出为字符串(而不是HTML)?正如你所看到的,我有工作和不工作的解决方案-我想知道为什么。谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-03 20:34:06

首先,disable-output-escaping是一个可选的序列化特性。此外,XSLT 2或3规范在根本不起作用时会详细说明,请参见https://www.w3.org/TR/xslt-30/#disable-output-escaping

如果在临时输出状态生效时对xsl:value-ofxsl:text指令禁用输出转义,则将忽略禁用输出转义的请求。

https://www.w3.org/TR/xslt-30/#dt-temporary-output-state

xsl:变量、xsl:param、xsl:with、xsl:function、xsl:key、xsl:sort、xsl:累加器-规则和xsl:merge-key总是在临时输出状态下计算包含的序列构造函数中的指令。

因此,在您的xsl:variable中,任何disable-output-escaping都不能工作。

使用它来构造SVG use元素的整个尝试是完全不必要的,您可以将任何结果元素创建为文字结果元素,例如<use xlink:href="{concat( '#', $svg-loc )}"></use> (该名称空间的属性范围内有适当的XLink名称空间声明),或者,如果需要计算部分名称或名称空间,则使用xsl:element

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55972533

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档