You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

XSLT插入SVG根节点问题:冗余命名空间与节点未添加求助

解决XSLT给SVG添加节点的两个问题

咱们先拆解你遇到的两个问题,再一步步给出修复方案:

问题1:<style>节点生成多余的xmlns属性

原因很直接:你直接写的<style>属于无命名空间元素,但SVG文档的所有核心元素都默认归属http://www.w3.org/2000/svg命名空间。当XSLT把无命名空间的<style>插入到SVG命名空间的上下文时,会自动添加xmlns=""来明确该元素不在父元素的命名空间里,再加上你的XSLT开头声明了xsi和svg前缀,这些属性就被连带生成了。

解决方法:用带svg前缀的<svg:style>创建元素,让它直接继承SVG命名空间,这样就不会产生多余的属性了。

问题2:<whatever>节点未被成功添加

这是因为你写了两个匹配svg:title的模板——XSLT处理时,当多个模板匹配同一节点且优先级相同时,只会执行最后一个模板(后面的模板会覆盖前面的),所以你的第一个模板逻辑被第二个覆盖,自然看不到<whatever>节点。

解决方法:把两个模板合并成一个,同时处理<style><whatever>的添加。

修复后的完整XSLT代码

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' 
                xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' 
                xmlns:svg="http://www.w3.org/2000/svg" 
                version='1.0'>

<!-- 默认复制所有节点和属性的模板 -->
<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

<!-- 合并svg:title的处理逻辑,同时添加style和whatever节点 -->
<xsl:template match="svg:title">
  <xsl:copy-of select="."/>
  <!-- 使用svg前缀的style元素,避免多余命名空间属性 -->
  <svg:style>.val{--valence: #4599a3}</svg:style>
  <!-- 若需要whatever也归属SVG命名空间,可改为<svg:whatever>foo</svg:whatever> -->
  <whatever>foo</whatever>
</xsl:template>

<xsl:template match="svg:defs/svg:circle">
  <xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:attribute name="style">fill: var(--valence, #47565b)</xsl:attribute>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>

额外小提示

如果你希望<whatever>也和其他SVG元素保持同一命名空间,只需要把它改成<svg:whatever>foo</svg:whatever>即可,这样它会自动继承SVG的命名空间属性,不会出现额外的xmlns声明。

内容的提问来源于stack exchange,提问作者DevonDahon

火山引擎 最新活动