├── DynamicXmlBuilder.sln ├── DynamicXmlBuilder ├── ChildNodesBuilder.cs ├── DynamicXmlBuilder.csproj ├── Properties │ └── AssemblyInfo.cs ├── XmlBuilder.cs └── XmlNodeBuilder.cs ├── DynamicXmlBuilderTest ├── App.config ├── DynamicXmlBuilderTest.csproj ├── Program.cs └── Properties │ └── AssemblyInfo.cs └── README.md /DynamicXmlBuilder.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.30110.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DynamicXmlBuilder", "DynamicXmlBuilder\DynamicXmlBuilder.csproj", "{D44E8AFE-7F7E-4B48-B1E0-0C85D0326BB4}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DynamicXmlBuilderTest", "DynamicXmlBuilderTest\DynamicXmlBuilderTest.csproj", "{D69B46F0-A038-438B-A951-8A4BE07E0F6C}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {D44E8AFE-7F7E-4B48-B1E0-0C85D0326BB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {D44E8AFE-7F7E-4B48-B1E0-0C85D0326BB4}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {D44E8AFE-7F7E-4B48-B1E0-0C85D0326BB4}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {D44E8AFE-7F7E-4B48-B1E0-0C85D0326BB4}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {D69B46F0-A038-438B-A951-8A4BE07E0F6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {D69B46F0-A038-438B-A951-8A4BE07E0F6C}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {D69B46F0-A038-438B-A951-8A4BE07E0F6C}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {D69B46F0-A038-438B-A951-8A4BE07E0F6C}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /DynamicXmlBuilder/ChildNodesBuilder.cs: -------------------------------------------------------------------------------- 1 | namespace DynamicXmlBuilder 2 | { 3 | using System.Collections.Generic; 4 | using System.Dynamic; 5 | using System.Linq; 6 | using System.Text; 7 | 8 | public class ChildXmlNodesBuilder : DynamicObject 9 | { 10 | private IList children; 11 | private XmlNodeBuilder parent; 12 | 13 | internal ChildXmlNodesBuilder(XmlNodeBuilder parent = null) 14 | { 15 | this.parent = parent; 16 | this.children = new List(); 17 | } 18 | 19 | public XmlNodeBuilder _d_ 20 | { 21 | get 22 | { 23 | return parent; 24 | } 25 | } 26 | 27 | public override bool TryGetMember(GetMemberBinder binder, out object result) 28 | { 29 | var nextNode = new XmlNodeBuilder(binder.Name, this.parent); 30 | this.AddNode(nextNode); 31 | result = nextNode; 32 | return true; 33 | } 34 | 35 | public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) 36 | { 37 | var innerText = (string)args[0]; 38 | Dictionary attr = null; 39 | if (args.Length > 1) 40 | { 41 | attr = args[1].GetType().GetProperties().ToDictionary(pr => pr.Name, pr => pr.GetValue(args[1]).ToString()); 42 | } 43 | var nextNode = new XmlNodeBuilder(binder.Name, this.parent, innerText, attr); 44 | this.AddNode(nextNode); 45 | result = nextNode; 46 | return true; 47 | } 48 | 49 | public string Build(int level) 50 | { 51 | var result = new StringBuilder(); 52 | foreach (var child in this.children) 53 | { 54 | result.AppendLine(child.Build(level)); 55 | } 56 | 57 | return result.ToString(); 58 | } 59 | 60 | internal void AddNode(XmlNodeBuilder node) 61 | { 62 | this.children.Add(node); 63 | } 64 | 65 | internal bool Any() 66 | { 67 | return this.children.Any(); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /DynamicXmlBuilder/DynamicXmlBuilder.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {D44E8AFE-7F7E-4B48-B1E0-0C85D0326BB4} 8 | Library 9 | Properties 10 | DynamicXmlBuilder 11 | DynamicXmlBuilder 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 55 | -------------------------------------------------------------------------------- /DynamicXmlBuilder/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("DynamicXmlBuilder")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("DynamicXmlBuilder")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("063348bd-10a8-4665-92c9-d5e63c93cd02")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /DynamicXmlBuilder/XmlBuilder.cs: -------------------------------------------------------------------------------- 1 | namespace DynamicXmlBuilder 2 | { 3 | public static class XmlBuilder 4 | { 5 | public static dynamic Create() 6 | { 7 | return new ChildXmlNodesBuilder(); 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /DynamicXmlBuilder/XmlNodeBuilder.cs: -------------------------------------------------------------------------------- 1 | namespace DynamicXmlBuilder 2 | { 3 | using System.Collections.Generic; 4 | using System.Dynamic; 5 | using System.Linq; 6 | using System.Text; 7 | 8 | public class XmlNodeBuilder : DynamicObject 9 | { 10 | private ChildXmlNodesBuilder children; 11 | private XmlNodeBuilder parent; 12 | private string name; 13 | private string innerText; 14 | private IDictionary attributes; 15 | 16 | internal XmlNodeBuilder(string tagName, XmlNodeBuilder parent, string innerText = null, IDictionary attributes = null) 17 | { 18 | this.children = new ChildXmlNodesBuilder(); 19 | this.parent = parent; 20 | this.name = tagName; 21 | this.innerText = innerText; 22 | this.attributes = attributes; 23 | } 24 | 25 | public ChildXmlNodesBuilder _b_ 26 | { 27 | get 28 | { 29 | this.children = new ChildXmlNodesBuilder(this); 30 | return this.children; 31 | } 32 | } 33 | 34 | public XmlNodeBuilder _d_ 35 | { 36 | get 37 | { 38 | return this.parent; 39 | } 40 | } 41 | 42 | public override bool TryGetMember(GetMemberBinder binder, out object result) 43 | { 44 | var nextNode = new XmlNodeBuilder(binder.Name, this.parent); 45 | this.parent.AddNode(nextNode); 46 | result = nextNode; 47 | return true; 48 | } 49 | 50 | public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) 51 | { 52 | var innerText = (string)args[0]; 53 | Dictionary attr = null; 54 | if (args.Length > 1) 55 | { 56 | attr = (Dictionary)args[1]; 57 | } 58 | var nextNode = new XmlNodeBuilder(binder.Name, this.parent, innerText, attr); 59 | this.parent.AddNode(nextNode); 60 | result = nextNode; 61 | return true; 62 | } 63 | 64 | internal void AddNode(XmlNodeBuilder node) 65 | { 66 | this.children.AddNode(node); 67 | } 68 | 69 | public string Build(int level = 0) 70 | { 71 | var result = new StringBuilder(); 72 | var whiteSpace = new string(' ', level * 4); 73 | result.Append(whiteSpace + "<" + this.name); 74 | if (this.attributes != null && this.attributes.Any()) 75 | { 76 | var attrAsString = new StringBuilder(" "); 77 | foreach (var attr in this.attributes) 78 | { 79 | attrAsString.Append(attr.Key + "=\"" + attr.Value + "\" "); 80 | } 81 | result.Append(attrAsString.ToString().TrimEnd()); 82 | } 83 | result.Append(">" + this.innerText); 84 | if (this.children.Any()) 85 | { 86 | result.AppendLine(whiteSpace).Append(this.children.Build(level + 1)); 87 | result.Append(whiteSpace + "" + whiteSpace); 88 | } 89 | else 90 | { 91 | result.Append(""); 92 | } 93 | 94 | return result.ToString(); 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /DynamicXmlBuilderTest/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /DynamicXmlBuilderTest/DynamicXmlBuilderTest.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {D69B46F0-A038-438B-A951-8A4BE07E0F6C} 8 | Exe 9 | Properties 10 | DynamicXmlBuilderTest 11 | DynamicXmlBuilderTest 12 | v4.5 13 | 512 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | {d44e8afe-7f7e-4b48-b1e0-0c85d0326bb4} 53 | DynamicXmlBuilder 54 | 55 | 56 | 57 | 64 | -------------------------------------------------------------------------------- /DynamicXmlBuilderTest/Program.cs: -------------------------------------------------------------------------------- 1 | namespace DynamicXmlBuilderTest 2 | { 3 | using System; 4 | 5 | using DynamicXmlBuilder; 6 | 7 | public class Program 8 | { 9 | public static void Main() 10 | { 11 | string xml = XmlBuilder.Create() 12 | .Customer._b_ 13 | .Name("Ivaylo", new { id = "unikat", change = "clickni" }) 14 | .Phone("0888-888-888") 15 | .Address._b_ 16 | .Street("In da gethou", new { @class = "css bate" }) 17 | .City("Kjustendja Baby") 18 | .Zip("Rar") 19 | ._d_ 20 | ._d_ 21 | .Build(); 22 | 23 | // prints 24 | // 25 | // Ivaylo 26 | // 0888-888-888 27 | //
28 | // In da gethou 29 | // Kjustendja Baby 30 | // Rar 31 | //
32 | //
33 | 34 | Console.WriteLine(xml); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /DynamicXmlBuilderTest/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("DynamicXmlBuilderTest")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("DynamicXmlBuilderTest")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("f094a3eb-4cba-4e12-a10b-44f12d96a894")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Dynamic XML Builder 2 | =================== 3 | 4 | Example: 5 | 6 | string xml = XmlBuilder.Create() 7 | .Customer._b_ 8 | .Name("Ivaylo", new { id = "unikat", change = "clickni" }) 9 | .Phone("0888-888-888") 10 | .Address._b_ 11 | .Street("In da gethou", new { @class = "css bate" }) 12 | .City("Kjustendja Baby") 13 | .Zip("Rar") 14 | ._d_ 15 | ._d_ 16 | .Build(); 17 | 18 | // prints 19 | // 20 | // Ivaylo 21 | // 0888-888-888 22 | //
23 | // In da gethou 24 | // Kjustendja Baby 25 | // Rar 26 | //
27 | //
28 | 29 | Console.WriteLine(xml); 30 | --------------------------------------------------------------------------------