Вот как я бы это сделал: я центрирую все вокруг центра холста SVG и смещаю первую и последнюю строку с помощью dy
text{text-anchor:middle;dominant-baseline:central;}
<svg style="border:1px solid black" width="200" height="300">
<text x="50%" y="50%" font-size="15">
<tspan x="100" y="150" dy="-1.2em" >tspan line 1</tspan>
<tspan x="100" y="150" >tspan line 2</tspan>
<tspan x="100" y="150" dy="1.2em" >tspan line 3</tspan>
</text>
</svg>
update
ФП прокомментировала, что они: обновили вопрос, чтобы отразить необходимость динамической вставки / удаления строк.
В этом случае я бы поместил весь текст в группу и использовал бы ограничивающий прямоугольник группы для центрирования текста:
Красный круг, который я добавил, просточтобы увидеть центр холста SVG.
let bb = txt.getBBox(); console.log()
let X = 100;
let Y = 150 - bb.y - (bb.height)/2;
txt.setAttributeNS(null,"transform",`translate(${X},${Y})`)
text{text-anchor:middle;dominant-baseline:central;font-size:15;}
<svg style="border:1px solid black" width="200" height="300">
<text id="txt"><!--
--><tspan x="0" y="0">tspan line 1</tspan><!--
--><tspan x="0" y="1.2em">tspan line 2</tspan><!--
--><tspan x="0" y="2.4em" >tspan line 3</tspan><!--
--><tspan x="0" y="3.6em" >tspan line 4</tspan>
</text>
<circle cx="100" cy="150" r="3" fill="red"/>
</svg>