使用带有 document() 的副本将 SVG 添加到 XHTML 输出

Posted

技术标签:

【中文标题】使用带有 document() 的副本将 SVG 添加到 XHTML 输出【英文标题】:Using copy-of with document() to add SVGs to XHTML output 【发布时间】:2013-09-03 16:31:04 【问题描述】:

在处理我的 XML 时,我正在尝试使用以下行将引用自 href 属性的 SVG 文件直接复制到我的输出 html 中:

 <xsl:copy-of copy-namespaces="yes" select="document(@href)"/>

copy-namespaces 应该不是必需的,因为无论如何默认值都是“yes”,但我添加了它以防止出现关于我是否尝试过的问题。

文件被复制到 HTML 中,但所有命名空间的元素都被删除了。例如,一个在被复制之前看起来像这样的文件:

  <rdf:RDF>
      <cc:Work rdf:about="">
        <dc:format>image/svg+xml</dc:format>
        <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
        <dc:title/>
      </cc:Work>
    </rdf:RDF>
  </metadata>
  <g transform="translate(-519.21143,-667.79077)" id="layer1">
    <image xlink:href="data:image/png;base64

之后是这样的:

  <_0:RDF xmlns:_0="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
      <_0:Work xmlns:_0="http://creativecommons.org/ns#" about="">
        <_0:format xmlns:_0="http://purl.org/dc/elements/1.1/">image/svg+xml</_0:format>
        <_0:type xmlns:_0="http://purl.org/dc/elements/1.1/" resource="http://purl.org/dc/dcmitype/StillImage"/>
        <_0:title xmlns:_0="http://purl.org/dc/elements/1.1/"/>
      </_0:Work>
    </_0:RDF>
  </metadata>
  <g id="layer1" transform="translate(-519.21143,-667.79077)">
    <image href="data:image/png;base64

图像元素的href 值上缺少 xlink 命名空间尤其成问题。

有什么想法可以在没有任何解释的情况下以不同的方式读取 SVG 文件吗?

我找到了一个“有效”的解决方案,但它是一个 hack,我想要更优雅的东西:

<xsl:template name="topic-image-svg">
    <!-- Generate tags to embed SWFs -->
    <xsl:element name="div">
      <xsl:if test="@width">
        <xsl:attribute name="width">
          <xsl:value-of select="@width"/>
        </xsl:attribute>
      </xsl:if>
      <xsl:if test="@height">
        <xsl:attribute name="height">
          <xsl:value-of select="@height"/>
        </xsl:attribute>
      </xsl:if>     
        <xsl:apply-templates select="document(@href)" mode="svg"/>
    </xsl:element>
  </xsl:template>

  <xsl:template match="*" mode="svg">
    <xsl:copy copy-namespaces="yes">
      <xsl:for-each select="@*">
        <xsl:choose>
          <xsl:when test="self::node()[name() = 'xlink:href']">
            <xsl:attribute name="xlink:href"><xsl:value-of select="."></xsl:value-of></xsl:attribute>
          </xsl:when>
          <xsl:otherwise>
            <xsl:copy></xsl:copy>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:for-each>
     <xsl:apply-templates mode="svg"></xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

【问题讨论】:

您的样式表是否在根标签中声明了所有命名空间? SVG 命名空间的格式是否正确?您显示的片段不包含前缀“xlink”的绑定。 您使用哪种 XSLT 2.0 处理器?您能否发布最少但完整的示例,以便我们重现问题?您使用哪种 XSLT 输出方法? 乍一看,它看起来像是您的 XSLT 处理器中的一个错误。但是当你说你将它复制到 HTML 文档时,我的怀疑就引起了。如果您将它添加到 HTML DOM,那么 HTML DOM 不是名称空间友好的,因此可能会发生各种事情。但是,您的标题显示“xHTML”。所以我认为我们需要了解更多:您使用的是什么 XSLT 处理器,以及您是如何运行它的? 您介意分享您的代码和实现吗?我很好奇至少能重现这个。 【参考方案1】:

我想你已经找到了这个 XSLT 操作的原因:

http://www.w3schools.com/xsl/el_namespace-alias.asp

在生成输出之前,当命名空间转换完成时,您的错位命名空间会保持原样。

【讨论】:

以上是关于使用带有 document() 的副本将 SVG 添加到 XHTML 输出的主要内容,如果未能解决你的问题,请参考以下文章

如何将带有css样式的内联SVG从浏览器保存/导出到图像文件

使用 SVG 渲染 Pdf 后,文本内容副本无法正常工作

带有 SVG 文档的 jQuery

如何使用javascript将svg use元素插入svg组?

包含带有 HTML 的 SVG 文件,并且仍然能够对它们应用样式?

将带有掩码和符号的 SVG 转换为纯 SVG 文件?