In HTML I can build a simple templating system by providing a template in form of a string, replace some parts of it and then assign it using innerHTML
to some
Here I write a dirty way...
innerHTML workaround for SVG
http://jsfiddle.net/microbians/8ztNU/
<html>
<body>
<svg id="svgcanvas">
</svg>
<script>
var twocircles='<circle cx="253" cy="562" r="10" stroke="black" stroke-width="2" fill="red"></circle> \
<circle cx="353" cy="562" r="10" stroke="black" stroke-width="2" fill="red"></circle>'
var receptacle = document.createElement('div');
var svgfragment='<svg>'+twocircles+'</svg>';
receptacle.innerHTML=''+svgfragment;
var Nodes=Array.prototype.slice.call(receptacle.childNodes[0].childNodes);
Nodes.forEach(function(el){document.getElementById('svgcanvas').appendChild(el)})
</script>
</body>
</html>
Enjoy!
The short answer is "No, there is nothing equivalent in the world of XML that lets you hand it a bit of markup and have it automatically create all the elements and attributes in the proper namespaces for the location where you insert it."
The closest direct answer is what @Robert has. As noted in my comments, even then you'll need to create any snippets inside an SVG document that has the same namespaces and prefixes as the document into which you'll be inserting the fragment.
Instead, you might find it is as easy (or easier) to use a convenience method on the standard DOM methods:
// Create a named SVG element on a node, with attributes and optional text
function appendTo(node,name,attrs,text){
var p,ns=appendTo.ns,svg=node,doc=node.ownerDocument;
if (!ns){ // cache namespaces by prefix once
while (svg&&svg.tagName!='svg') svg=svg.parentNode;
ns=appendTo.ns={svg:svg.namespaceURI};
for (var a=svg.attributes,i=a.length;i--;){
if (a[i].namespaceURI) ns[a[i].localName]=a[i].nodeValue;
}
}
var el = doc.createElementNS(ns.svg,name);
for (var attr in attrs){
if (!attrs.hasOwnProperty(attr)) continue;
if (!(p=attr.split(':'))[1]) el.setAttribute(attr,attrs[attr]);
else el.setAttributeNS(ns[p[0]]||null,p[1],attrs[attr]);
}
if (text) el.appendChild(doc.createTextNode(text));
return node.appendChild(el);
}
function clear(node){
while (node.lastChild) node.removeChild(node.lastChild);
}
With this you can do things like:
var icons={
Apps : "/images/apps.png",
Games : "/images/games.png"
}
var wrap = document.querySelector('#container');
clear(wrap);
for (var label in icons){
if (!icons.hasOwnProperty(label)) continue;
var icon = appendTo(wrap,'g',{'class':'icon'});
appendTo(icon,'image',{'xlink:href':icons[label]});
appendTo(icon,'text',{x:10,y:20},label);
}
This is IMHO cleaner than trying to construct the raw SVG markup using string concatenation:
var svg = [];
for (var label in icons){
if (!icons.hasOwnProperty(label)) continue;
svg.push('<g class="icon">');
svg.push('<image xlink:href="'+icons[label]+'" />');
svg.push('<text x="10" y="20">'+label+'</text>');
svg.push('</g>');
}
wrap.innerSVG = svg.join(''); // doesn't work, of course