Convert svg to embedded svg with XSLT
Posted: Thu Nov 18, 2021 1:57 am
Hi,
I would like to convert a svg file opened in Oxygen with xslt so that I can copy and paste it into a DITA svg container.
The xslt brings only limited success and some additional manual work is unfortunately required.
Example file:
Desired result:
1. remove namespace declartion in root element
2. add namespace prefix for all elements (svg:)
3. remove @id in all elements, except in linearGradient
4. remove tspan in text
Current result (namespace in root element and tspan are not removed):
My XSLT:
The if-query is certainly messy. But I couldn't do it any other way. Templates for concrete elements don't seem to do anything at all.
Can anyone give me tips on what I'm doing wrong?
Thanks a lot
Regards
Apollo
I would like to convert a svg file opened in Oxygen with xslt so that I can copy and paste it into a DITA svg container.
The xslt brings only limited success and some additional manual work is unfortunately required.
Example file:
Code: Select all
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 919 647" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(1,0,0,1,-214.985,-499.215)">
<g id="Alles">
<g id="Test">
<rect x="535.908" y="574.988" width="387.783" height="222.864" style="fill:rgb(235,235,235);"/>
<circle cx="976.064" cy="897.026" r="152.662" style="fill:rgb(235,235,235);"/>
</g>
<rect x="576.024" y="1020.72" width="557.159" height="124.804" style="fill:url(#_Linear1);"/>
</g>
</g>
<text x="166.628px" y="336.867px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:33.333px;">Audit-T<tspan x="272.829px 283.929px " y="336.867px 336.867px ">ra</tspan>il</text>
<defs>
<linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(557.159,0,0,124.804,576.024,1083.12)"><stop offset="0" style="stop-color:black;stop-opacity:1"/><stop offset="1" style="stop-color:rgb(235,235,235);stop-opacity:1"/></linearGradient>
</defs>
</svg>
1. remove namespace declartion in root element
2. add namespace prefix for all elements (svg:)
3. remove @id in all elements, except in linearGradient
4. remove tspan in text
Code: Select all
<svg:svg width="100%" height="100%" viewBox="0 0 919 647" version="1.1" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;" preserveAspectRatio="xMidYMid meet" zoomAndPan="magnify" contentScriptType="text/ecmascript" contentStyleType="text/css">
<svg:g transform="matrix(1,0,0,1,-214.985,-499.215)">
<svg:g>
<svg:g>
<svg:rect x="535.908" y="574.988" width="387.783" height="222.864" style="fill:rgb(235,235,235);"/>
<svg:circle cx="976.064" cy="897.026" r="152.662" style="fill:rgb(235,235,235);"/>
</svg:g>
<svg:rect x="576.024" y="1020.72" width="557.159" height="124.804" style="fill:url(#_Linear1);"/>
</svg:g>
</svg:g>
<svg:text x="166.628px" y="336.867px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:33.333px;">Audit-Trail</svg:text>
<svg:defs>
<svg:linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" xlink:type="simple" xlink:show="other" xlink:actuate="onLoad"><svg:stop offset="0" style="stop-color:black;stop-opacity:1"/><svg:stop offset="1" style="stop-color:rgb(235,235,235);stop-opacity:1"/></svg:linearGradient>
</svg:defs>
</svg:svg>
Current result (namespace in root element and tspan are not removed):
Code: Select all
<svg:svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:serif="http://www.serif.com/" xmlns:svg="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 919 647" version="1.1" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;" preserveAspectRatio="xMidYMid meet" zoomAndPan="magnify" contentScriptType="text/ecmascript" contentStyleType="text/css">
<svg:g transform="matrix(1,0,0,1,-214.985,-499.215)">
<svg:g>
<svg:g>
<svg:rect x="535.908" y="574.988" width="387.783" height="222.864" style="fill:rgb(235,235,235);"/>
<svg:circle cx="976.064" cy="897.026" r="152.662" style="fill:rgb(235,235,235);"/>
</svg:g>
<svg:rect x="576.024" y="1020.72" width="557.159" height="124.804" style="fill:url(#_Linear1);"/>
</svg:g>
</svg:g>
<svg:text x="166.628px" y="336.867px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:33.333px;">Audit-T<svg:tspan x="272.829px 283.929px " y="336.867px 336.867px ">ra</svg:tspan>il</svg:text>
<svg:defs>
<svg:linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" xlink:type="simple" xlink:show="other" xlink:actuate="onLoad"><svg:stop offset="0" style="stop-color:black;stop-opacity:1"/><svg:stop offset="1" style="stop-color:rgb(235,235,235);stop-opacity:1"/></svg:linearGradient>
</svg:defs>
</svg:svg>
My XSLT:
Code: Select all
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xlink="http://www.w3.org/1999/xlink/"
xmlns:svg="http://www.w3.org/2000/my/"
xmlns:serif="http://www.serif.com/"
exclude-result-prefixes="svg serif xlink" >
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes" exclude-result-prefixes="svg serif xlink"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@xlink:noNamespaceSchemaLocation"/>
<xsl:template match="@serif:noNamespaceSchemaLocation"/>
<xsl:template match="@svg:noNamespaceSchemaLocation"/>
<xsl:template match="tspan" priority="1000"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@serif:id"/>
<xsl:template match="@gradientUnits"/>
<xsl:template match="@gradientTransform"/>
<xsl:template match="@id"/>
<xsl:template match="*" priority="100">
<xsl:element name="svg:{name()}" namespace="{namespace-uri()}">
<xsl:copy-of select="namespace::*[not(. = 'http://www.w3.org/1999/xlink/')]" />
<xsl:variable name="localName" select="local-name()"/>
<!-- keep @id for linearGradient -->
<xsl:if test="$localName = 'linearGradient'">
<xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute>
</xsl:if>
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
The if-query is certainly messy. But I couldn't do it any other way. Templates for concrete elements don't seem to do anything at all.
Can anyone give me tips on what I'm doing wrong?
Thanks a lot
Regards
Apollo