private XElement PopulateTree(XElement current, Func <DataMapping, IEnumerable <XElement> > parentGetter, Func <DataMapping, string> calculatedGetter) { calculatedGetter = calculatedGetter ?? (Func <DataMapping, string>)(m => m.Value); MappedType lastType = null; IEnumerable <XElement> parents = Enumerable.Repeat(current, 1); foreach (var mapping in _mappings) { if (mapping.Type != lastType) { if (lastType != null) { if (mapping.Type.ItemType.Relationship == null) { current = current.AddAndReturn(new XElement("related_id")); } else { current = current.AddAndReturn(new XElement("Relationships")); } } parents = null; if (parentGetter != null) { parents = parentGetter.Invoke(mapping); } if (parents == null) { current = current.AddAndReturn(new XElement("Item", new XAttribute("type", mapping.Type.ItemType.Name), new XAttribute("typeid", mapping.Type.ItemType.Id) )); parents = Enumerable.Repeat(current, 1); } var id = _mappings.FirstOrDefault(m => m.Type == mapping.Type && m.Property != null && m.Property.Name == "id"); if (id != null) { foreach (var parent in parents) { current.Add(new XAttribute("id", id.IsCalculated ? "{" + id.Value + "}" : id.Value)); } } } if (mapping.Property != null) { foreach (var parent in parents) { switch (mapping.Property.Type) { case PropertyType.Item: parent.Add(new XElement(mapping.Property.Name, new XElement("Item", new XAttribute("type", mapping.Property.ItemSource.Name), new XAttribute("action", "get"), new XElement("keyed_name", mapping.IsCalculated ? (object)new XElement(_nsXsl + "value-of", new XAttribute("select", calculatedGetter.Invoke(mapping))) : mapping.Value ) ) )); break; case PropertyType.Date: parent.Add(new XElement(mapping.Property.Name, mapping.IsCalculated ? (object)new XElement(_nsXsl + "value-of", new XAttribute("select", "arasx:FormatDate(" + calculatedGetter.Invoke(mapping) + ", 's')")) : (string.IsNullOrEmpty(mapping.Value) ? "" : DateTime.Parse(mapping.Value).ToString("s")) )); break; default: parent.Add(new XElement(mapping.Property.Name, mapping.IsCalculated ? (object)new XElement(_nsXsl + "value-of", new XAttribute("select", calculatedGetter.Invoke(mapping))) : mapping.Value )); break; } } } lastType = mapping.Type; } return(current); }