import std.traits; import std.conv; import arsd.dom; // you could use another xml lib too, but I like mine interface ReflectionInfo { Object fromElement(Element xmlElement); } ReflectionInfo makeReflection(T)() if(is(T : Object)) { alias void delegate(T t, Element data)[string] MemberSetters; static MemberSetters makeMemberSetters() { MemberSetters setters; auto a = new T(); void delegate(T t, Element data) makeSetter(int i)(string name) { return delegate void(T t, Element data) { static if(is(typeof(thing) : Object)) { // objects come from child nodes // FIXME: implement this } else { // other types are assumed to be primitives t.tupleof[i] = to!(typeof(t.tupleof[i]))(data.innerText); } }; } foreach(i, thing; a.tupleof) { auto name = a.tupleof[i].stringof[2..$]; setters[name] = makeSetter!(i)(name); } return setters; } return new class ReflectionInfo { MemberSetters memberSetters; this() { memberSetters = makeMemberSetters(); } override Object fromElement(Element xmlElement) { T t = new T(); foreach(child; xmlElement.childNodes) { if(child.nodeType == NodeType.Text) continue; // skip whitespace auto member = child.tagName; auto setter = member in memberSetters; if(setter !is null) { (*setter)(t, child); } else { // you could throw here, but I just want to ignore unknown members } } return t; } }; } class ReflectionCollection { ReflectionInfo[string] types; void addType(T)() if(is(T : Object)) { pragma(msg, T.stringof ~ " added to understanding"); types[T.stringof] = makeReflection!T; } Object[] readFromXml(Document document) { Object[] returned; foreach(object; document.root.childNodes) { if(object.nodeType == NodeType.Text) continue; // skip whitespace and stuff if(object.tagName in types) returned ~= types[object.tagName].fromElement(object); } return returned; } } /* Usage */ class Person { string name; uint age; override string toString() { import std.string; return format("Person: %s (Age: %d)", name, age); } } void main() { auto info = new ReflectionCollection(); info.addType!Person; auto document = new XmlDocument(` Adam 25 Ken 69 `); auto objects = info.readFromXml(document); import std.stdio; writeln(objects); }