I am totally new to XSLT, so please bear with me. I have svg files whose structure is as such:
<?xml-stylesheet type="text/xsl" href="TextAddition.xsl"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="exportSvg" width="600" height="600">
<defs/>
<rect width="600" height="600" transform="translate(0, 0)" fill="rgb(255, 255, 255)" style="fill:rgb(255, 255, 255);"/>
<g>
<g id="Drawing-svg" clip-path="url(#rect-mask-Drawing)">
<clipPath id="rect-mask-Drawing">
<rect x="0" y="0" width="600" height="600"/>
</clipPath>
<g id="chart-svg">
<g id="svg-main" clip-path="url(#rect-mask-Main)">
<clipPath id="rect-mask-Main">
<rect x="0" y="0" width="600" height="600"/>
</clipPath>
<g id="Drawing-svg">
<g id="Parts-svg">
<g id="Section-svg">
<path d="M150 0 L75 200 L225 200 Z" stroke="rgb(100, 100, 100)" style="fill: rgb(100, 100, 100); stroke-width: 0.3; stroke-linejoin: round; stroke-linecap: round; stroke rgb(100, 100, 100);"/>
<g id="symbols-svg">
<g id="Item1-svg" transform="translate(105, 210)">
<path d="M-5 0a5 5 0 1 0 10 0 5 5 0 1 0-10 0Z" stroke="rgb(200, 200, 200)" id="Item1" style="fill: rgb(0, 15, 60); stroke-width: 1; fill-opacity: 0.9; stroke-opacity: 0.5; stroke-linejoin: miter; stroke-linecap: butt; stroke: rgb(0, 50, 100);"/>
</g>
<g id="Item2-svg" transform="translate(250, 90)">
<path d="M-5 0a5 5 0 1 0 10 0 5 5 0 1 0-10 0Z" stroke="rgb(200, 200, 200)" id="Item2" style="fill: rgb(0, 15, 60); stroke-width: 1; fill-opacity: 0.9; stroke-opacity: 0.5; stroke-linejoin: miter; stroke-linecap: butt; stroke: rgb(0, 50, 100);"/>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>
The resulting file I would like to have is this:
<?xml-stylesheet type="text/xsl" href="TextAddition.xsl"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="exportSvg" width="600" height="600">
<defs/>
<rect width="600" height="600" transform="translate(0, 0)" fill="rgb(255, 255, 255)" style="fill:rgb(255, 255, 255);"/>
<g>
<g id="Drawing-svg" clip-path="url(#rect-mask-Drawing)">
<clipPath id="rect-mask-Drawing">
<rect x="0" y="0" width="600" height="600"/>
</clipPath>
<g id="chart-svg">
<g id="svg-main" clip-path="url(#rect-mask-Main)">
<clipPath id="rect-mask-Main">
<rect x="0" y="0" width="600" height="600"/>
</clipPath>
<g id="Drawing-svg">
<g id="Parts-svg">
<g id="Section-svg">
<path d="M150 0 L75 200 L225 200 Z" stroke="rgb(100, 100, 100)" style="fill: rgb(100, 100, 100); stroke-width: 0.3; stroke-linejoin: round; stroke-linecap: round; stroke rgb(100, 100, 100);"/>
<g id="symbols-svg">
<g id="Item1-svg" transform="translate(105, 210)">
<path d="M-5 0a5 5 0 1 0 10 0 5 5 0 1 0-10 0Z" stroke="rgb(200, 200, 200)" id="Item1" style="fill: rgb(0, 15, 60); stroke-width: 1; fill-opacity: 0.9; stroke-opacity: 0.5; stroke-linejoin: miter; stroke-linecap: butt; stroke: rgb(0, 50, 100);"/>
<text x="" y="" id="Item1-text">
<tspan id="Item1-text" x="" y="" >Item1
</tspan>
</text>
</g>
<g id="Item2-svg" transform="translate(250, 90)">
<path d="M-5 0a5 5 0 1 0 10 0 5 5 0 1 0-10 0Z" stroke="rgb(200, 200, 200)" id="Item2" style="fill: rgb(0, 15, 60); stroke-width: 1; fill-opacity: 0.9; stroke-opacity: 0.5; stroke-linejoin: miter; stroke-linecap: butt; stroke: rgb(0, 50, 100);"/>
<text x="" y="" id="Item2-text">
<tspan id="Item2-text" x="" y="" >Item2
</tspan>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>
In which, for each grouped Itemn part of the group symbols the following text block is added, being Itemn a match of name of the symbol it refers to. This is course a skeleton of the files I would like to work on, so there could be hundreds on Itemn and each of them would have its name displayed.
<text x="" y="" id="Itemn-text">
<tspan id="Itemn-text" x="" y="" >Itemn
</tspan>
</text>
And below the TextAddition.xsl
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" >
<xsl:output method="xml" indent="yes" standalone="no" doctype-public="-//W3C//DTD SVG 1.1//EN" doctype-system="http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" media-type="image/svg" />
<xsl:template match="/">
<xsl:for-each select="..."> <!-- Here-->
</xsl:template>
</xsl:stylesheet>
I am assuming the XSL file is well formed since i can see the file in the browser (code take from https://edutechwiki.unige.ch/en/XSLT_to_generate_SVG_tutorial) I understand I can modify it through XSLT, yet I do not know how to point to each of the symbols in order to add the text for each of them. Could someone please advise?
CodePudding user response:
For XSLT 3:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
exclude-result-prefixes="#all"
version="3.0">
<xsl:strip-space elements="*"/>
<xsl:template match="svg:*[@id[starts-with(., 'Item')]]">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
<xsl:variable name="id" select="substring-before(@id, '-')"/>
<text x="" y="" id="{$id}-text">
<tspan id="{$id}-tspan" x="" y="">
<xsl:value-of select="$id"/>
</tspan>
</text>
</xsl:copy>
</xsl:template>
<xsl:mode on-no-match="shallow-copy"/>
</xsl:stylesheet>
For XSLT 1:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
exclude-result-prefixes="svg"
version="1.0">
<xsl:strip-space elements="*"/>
<xsl:template match="svg:*[@id[starts-with(., 'Item')]]">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
<xsl:variable name="id" select="substring-before(@id, '-')"/>
<text x="" y="" id="{$id}-text">
<tspan id="{$id}-tspan" x="" y="">
<xsl:value-of select="$id"/>
</tspan>
</text>
</xsl:copy>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>