skip to Main Content

I need to save my DOM structure as SVG image. To do so I transform some elements according to SVG standards.
SVG demands that line break and img tag shall have closing tags.

When I try to replace them in innerHTML, it automatically converts back to html standards (without closing tag). The same when I just add closing line break tag, I just get two break tags.

Is there a way to convert it to SVG standards?

var someText1 = main.getElementsByTagName("span")[0];
someText1.innerHTML = someText1.innerHTML.replace(/<br>/g, '<br />');
console.log(someText1.innerHTML);

var someText2 = main.getElementsByTagName("span")[1];
someText2.innerHTML = someText2.innerHTML.replace(/<br>/g, '<br></br>');
console.log(someText2.innerHTML);
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 500 500">
  <foreignObject id="main" width="100%" height="100%" x="0" y="0">
    <span>one<br>two</span>
    <span>three<br>four</span>
  </foreignObject>
</svg>

3

Answers


  1. You are using replace string with .innerHTML which is work with string and when browser render out what you request, it will be just HTML (valid HTML).
    I’m not good to explain more about this but I suggest you to read this page because they have very well explained.

    To make your <br> to be valid SVG, I recommend you to use DOM object instead.

    First create br element into a variable.

    const brElement = document.createElementNS("http://www.w3.org/2000/svg", 'br');
    

    And then replace them. Here is full code.

    const brElement = document.createElementNS("http://www.w3.org/2000/svg", 'br');
    var someText1 = main.getElementsByTagName("span")[0];
    someText1.querySelector('br').replaceWith(brElement);
    console.log(someText1.innerHTML);
    
    var someText2 = main.getElementsByTagName("span")[1];
    someText2.querySelector('br').replaceWith(brElement);
    console.log(someText2.innerHTML);
    <svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 500 500">
      <foreignObject id="main" width="100%" height="100%" x="0" y="0">
        <span>one<br>two</span>
        <span>three<br>four</span>
      </foreignObject>
    </svg>

    Once the code runned, it will be change <br> to be <br></br> and I hope that is valid SVG as you want.

    Edit:
    As mentioned by @Robert Longson , the br tag is not in SVG element reference it maybe invalid tag and I don’t see any result from it (no new line). So, I suggest to change it to something else, or remove it instead, (or maybe keep using for some reason).

    Login or Signup to reply.
  2. You are using HTML serialisation when you need to be using XML serialisation. Fortunately browsers have an XML serialiser.

    var someText1 = main.getElementsByTagName("span")[0];
    console.log(new XMLSerializer().serializeToString(someText1));
    
    var someText2 = main.getElementsByTagName("span")[1];
    console.log(new XMLSerializer().serializeToString(someText2));
    
    var wholeThing = main.parentElement;
    console.log(new XMLSerializer().serializeToString(wholeThing));
    <svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 500 500">
      <foreignObject id="main" width="100%" height="100%" x="0" y="0">
        <span>one<br>two</span>
        <span>three<br>four</span>
      </foreignObject>
    </svg>
    Login or Signup to reply.
  3. The issue here is not how you can change the HTML markup or how ou add elements to the DOM, but how you can turn the DOM into a XML document.

    Use the XMLSerializer for taking the DOM element and output a XML string:

    Btw. remember to use the HTML namespace for the elements inside the foreignObject.

    const svgelm = document.querySelector('svg');
    
    const s = new XMLSerializer();
    let xmlstr = s.serializeToString(svgelm);
    console.log(xmlstr);
    <svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 500 500">
      <foreignObject id="main" width="100%" height="100%" x="0" y="0">
        <span xmlns="http://www.w3.org/1999/xhtml">one<br>two</span>
        <span xmlns="http://www.w3.org/1999/xhtml">three<br>four</span>
      </foreignObject>
    </svg>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search