Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using copy-of with document() to add SVGs to XHTML output

While processing my XML, I'm trying to copy an SVG file referenced from an href attribute directly into my output HTML with the following line:

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

The copy-namespaces should not be necessary since the default value is "yes" anyway, but I've added it to prevent questions about whether or not I've tried it.

The files are copied into the HTML, but any namespaced elements are hosed. For example, a file that looks like this before being copied:

  <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

Looks like this afterwards:

  <_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

The missing xlink namespace on the href value of the image element is particularly problematic.

Any thoughts on how I can do this differently to read in the SVG file without any interpretation?

I've found one solution that "works", but it's a hack and I'd like something more elegant:

<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>
like image 691
jrhooker Avatar asked Aug 30 '13 21:08

jrhooker


1 Answers

I think you've hit upon the reason for this XSLT operation:

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

which leaves your mangled namespaces intact until output is generated, when the namespace transformation is done.

like image 60
Oldest Software Guy Avatar answered Oct 17 '22 10:10

Oldest Software Guy