Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get SVG root element and its children from an <object> node to export SVG with dynamic content

I have made a billing model made in InkScape (because I love SVG). I'd like to generate new SVG without having to do it manually in InkScape (update the date, the amount, the customer email etc).

To achieve that this is what I've came up so far (a lot of this code where found on other post about SVG and Javscript) :

To make it easy, let's say I have a HTML page with an which is displaying my billing model

<button onclick="addDownloadLink()">Add download hyperlink</button>
<br />
<div id="exportLinkContainer"></div>
<br />
<!-- Size is based on a ratio of 210x297 -->
<object id="svgObject" data="./BillingModel.svg" type="image/svg+xml" width="630" height="891">No SVG support</object>

On a button action, i call a javascript function

function addDownloadLink() {
    var svgObject = document.getElementById("svgObject").contentDocument;

    // THIS IS HERE where I can't find how to get the root svg element and all its attributs.
    var svg = svgObject.getElementById("svg").innerHTML;
    var svg2 = svgObject.getElementsByTagName("svg")[0].innerHTML;
    console.log("svg: " + svg);
    console.log("svg2: " + svg2);

    var blob = new Blob([svg], { type: "image/svg+xml;charset=utf-8" });
    var dateNow = new Date().toLocaleDateString();
    var downloadLink = document.createElement("a");
    downloadLink.appendChild(document.createTextNode("Download " + dateNow));
    downloadLink.setAttribute("download", "BillingExport___" + dateNow + ".svg");
    downloadLink.setAttribute("target", "_blank");
    downloadLink.setAttribute("href-lang", 'image/svg+xml');
    downloadLink.setAttribute("href", URL.createObjectURL(blob));

    var exportLinkContainer = document.getElementById("exportLinkContainer");
    exportContainer.innerHTML = '';
    exportContainer.appendChild(downloadLink);
}

And here is an exemple of my svg file named BillingExportModel.svg :

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
    xmlns:dc="http://purl.org/dc/elements/1.1/"
    xmlns:cc="http://creativecommons.org/ns#"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:svg="http://www.w3.org/2000/svg"
    xmlns="http://www.w3.org/2000/svg"
    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
    sodipodi:docname="BillingExportModel.svg"
    inkscape:export-filename="/Users/Racine/Desktop/facture_1703_microsoft.png"
    height="297mm"
    width="210mm"
    inkscape:export-xdpi="202"
    version="1.1"
    inkscape:export-ydpi="202"
    inkscape:version="0.91 r13725"
    viewBox="0 0 210 297"
    id="svg">
    <!-- My script manage to get everything here inside the SVG root element. I need to get its parent and all its attributs. -->
    <!-- presentation stuff etc hidden because of not being usefull -->
    <text
        style="word-spacing:0px;letter-spacing:0px"
        line-height="125%"
        xml:space="preserve"
        y="134.65009"
        x="175.17645"
        sodipodi:linespacing="125%"
        id="text206">
        <tspan
            id="TextArticleTotal"
            sodipodi:role="line"
            x="175.17645"
            y="134.65009">1 450,00 €</tspan>
    </text>
    <!-- etc etc etc -->
</svg>

It almost works expet that I don't manage to get the svg root element and all attributs like viewbox etc. But I have all the SVG content which is nice.

I can still copy all the svg root node inside my script in a var and concatenate that with I manage to have but I'm not happy with this solution and think I can do better.

Any help would be very appreciate ;) Thanks

like image 639
Nk54 Avatar asked Nov 24 '25 11:11

Nk54


1 Answers

Substitute outerHTML where you currently have innerHTML and use documentElement to get the root element. outerHTML returns the element itself and its descendants rather than just the descendants.

So the working lines are:

var svgObject = document.getElementById("svgObject");
var svg = svgObject.documentElement.outerHTML;

You don't need to give the root element an id unless you particularly want to.

As an aside setting href-lang to image/svg+xml is wrong too. The attribute to set with that value is type.

like image 142
Robert Longson Avatar answered Nov 26 '25 23:11

Robert Longson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!