├── .gitignore ├── README.md └── src ├── XmlModel.sln ├── XmlModel ├── Properties │ └── AssemblyInfo.cs ├── XModel.cs ├── XmlModel.csproj ├── XmlModel.nuspec └── XmlTags.cs └── XmlModelTest ├── App.config ├── Program.cs ├── Properties └── AssemblyInfo.cs └── XmlModelTest.csproj /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | 46 | [Dd]ebug/ 47 | [Rr]elease/ 48 | x64/ 49 | build/ 50 | [Bb]in/ 51 | [Oo]bj/ 52 | 53 | # MSTest test Results 54 | [Tt]est[Rr]esult*/ 55 | [Bb]uild[Ll]og.* 56 | 57 | *_i.c 58 | *_p.c 59 | *.ilk 60 | *.meta 61 | *.obj 62 | *.pch 63 | *.pdb 64 | *.pgc 65 | *.pgd 66 | *.rsp 67 | *.sbr 68 | *.tlb 69 | *.tli 70 | *.tlh 71 | *.tmp 72 | *.tmp_proj 73 | *.log 74 | *.vspscc 75 | *.vssscc 76 | .builds 77 | *.pidb 78 | *.log 79 | *.scc 80 | 81 | # Visual C++ cache files 82 | ipch/ 83 | *.aps 84 | *.ncb 85 | *.opensdf 86 | *.sdf 87 | *.cachefile 88 | 89 | # Visual Studio profiler 90 | *.psess 91 | *.vsp 92 | *.vspx 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | 101 | # TeamCity is a build add-in 102 | _TeamCity* 103 | 104 | # DotCover is a Code Coverage Tool 105 | *.dotCover 106 | 107 | # NCrunch 108 | *.ncrunch* 109 | .*crunch*.local.xml 110 | 111 | # Installshield output folder 112 | [Ee]xpress/ 113 | 114 | # DocProject is a documentation generator add-in 115 | DocProject/buildhelp/ 116 | DocProject/Help/*.HxT 117 | DocProject/Help/*.HxC 118 | DocProject/Help/*.hhc 119 | DocProject/Help/*.hhk 120 | DocProject/Help/*.hhp 121 | DocProject/Help/Html2 122 | DocProject/Help/html 123 | 124 | # Click-Once directory 125 | publish/ 126 | 127 | # Publish Web Output 128 | *.Publish.xml 129 | *.pubxml 130 | *.publishproj 131 | 132 | # NuGet Packages Directory 133 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 134 | #packages/ 135 | 136 | # Windows Azure Build Output 137 | csx 138 | *.build.csdef 139 | 140 | # Windows Store app package directory 141 | AppPackages/ 142 | 143 | # Others 144 | sql/ 145 | *.Cache 146 | ClientBin/ 147 | [Ss]tyle[Cc]op.* 148 | ~$* 149 | *~ 150 | *.dbmdl 151 | *.[Pp]ublish.xml 152 | *.pfx 153 | *.publishsettings 154 | 155 | # RIA/Silverlight projects 156 | Generated_Code/ 157 | 158 | # Backup & report files from converting an old project file to a newer 159 | # Visual Studio version. Backup files are not needed, because we have git ;-) 160 | _UpgradeReport_Files/ 161 | Backup*/ 162 | UpgradeLog*.XML 163 | UpgradeLog*.htm 164 | 165 | # SQL Server files 166 | App_Data/*.mdf 167 | App_Data/*.ldf 168 | 169 | ############# 170 | ## Windows detritus 171 | ############# 172 | 173 | # Windows image file caches 174 | Thumbs.db 175 | ehthumbs.db 176 | 177 | # Folder config file 178 | Desktop.ini 179 | 180 | # Recycle Bin used on file shares 181 | $RECYCLE.BIN/ 182 | 183 | # Mac crap 184 | .DS_Store 185 | 186 | 187 | ############# 188 | ## Python 189 | ############# 190 | 191 | *.py[cod] 192 | 193 | # Packages 194 | *.egg 195 | *.egg-info 196 | dist/ 197 | build/ 198 | eggs/ 199 | parts/ 200 | var/ 201 | sdist/ 202 | develop-eggs/ 203 | .installed.cfg 204 | 205 | # Installer logs 206 | pip-log.txt 207 | 208 | # Unit test / coverage reports 209 | .coverage 210 | .tox 211 | 212 | #Translations 213 | *.mo 214 | 215 | #Mr Developer 216 | .mr.developer.cfg 217 | .vs/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # XmlModel 2 | An object mapping to xml, makes xml CURD operation quickly like operate an object. 3 | ## Install 4 | Download source code generate it yourself or search `XmlModel` in nuget or excute command below. 5 | ``` 6 | Install-Package XmlModel 7 | ``` 8 | ## Classes 9 | * `XModel` Class use to create read xml file and find node, represent a xml file. 10 | * `XmlTag` A abstract model of xml node.Has two properties **Name** and **Attrs** as xml node's Name and Attributes. 11 | * `XmlChildTag` Inherit of XmlTag, model of a xml node that have child node.Has Two List **ChildTagList** and **BaseTagList** as xml node's child node. 12 | * `XmlBaseTag` Inherit of XmlTag, model of a xml node that don't have child.Has a property **InnerText** as xml node's inner text. 13 | 14 | ## Usage 15 | **`Using XmlModel;`** 16 | 17 | **`Create`** a xml file must have a root, root is XmlTag Type, so you must create a XmlChildTag or XmlBaseTag as root. 18 | Use constructor new a XModel then the xml file is created. 19 | The parameters are **FileDirectory**, **FileName**, **EncodeType**, **RootTag** 20 | ```c# 21 | XmlChildTag rootTag = new XmlChildTag("Root"); 22 | rootTag.BaseTagList.Add(new XmlBaseTag("BaseTagOne")); 23 | XModel myXModel = new XModel("D:\\XML\\", "MyXModel.xml", "utf-8", rootTag); 24 | ``` 25 | **`Read`** a xml file use two parameters **Directory** and **FileName** constructor a new XModel.Use XmlChildTag's ChildTagList and BaseTagList find a node. 26 | ```c# 27 | XModel myXml = new XModel("D:\\XML\\", "MyXModel.xml"); 28 | string rootName = myXml.Root.Name; 29 | string baseTagOneName = (myXml.Root as XmlChildTag).BaseTagList.First().Name; 30 | ``` 31 | **`Edit`** a xml file just read it then edit the XModel's root and save.Edit root just some object operations of XmlChildTag and XmlBaseTag. 32 | ```c# 33 | XModel myXml = new XModel("D:\\XML\\", "MyXModel.xml"); 34 | //edit root name and attributes 35 | XmlChildTag root = myXml.Root as XmlChildTag; 36 | root.Name = "NewRoot"; 37 | root.Attrs.Add("attr1", "value1"); 38 | //root add a child tag which have three base tag 39 | XmlChildTag newChild = new XmlChildTag("NewChild"); 40 | newChild.BaseTagList.Add(new XmlBaseTag("BaseTagTwo")); 41 | 42 | XmlBaseTag baseTagThree = new XmlBaseTag("BaseTagThree"); 43 | baseTagThree.Attrs.Add("testa", "testv"); 44 | newChild.BaseTagList.Add(baseTagThree); 45 | 46 | newChild.BaseTagList.Add(new XmlBaseTag("BaseTagFour") { InnerText = "some text" }); 47 | root.ChildTagList.Add(newChild); 48 | //save to file 49 | myXml.Save(); 50 | ``` 51 | **`QuicklyGet`** is an method provide on XModel, XmlChildTag, XmlBaseTag. Input xml node's name in order then it will return the node you want.Because it's all objects You can use lambda or your own code get what else you want. 52 | ```c# 53 | XModel myXml = new XModel("D:\\XML\\", "MyXModel.xml"); 54 | //GetChildTag 55 | XmlChildTag childA = myXml.GetChildTag("NewRoot", "NewChild"); 56 | childA.Attrs.Add("find", "ture"); 57 | 58 | //GetBaseTag 59 | XmlBaseTag baseTagTwo = myXml.GetBaseTag("NewRoot", "NewChild", "BaseTagTwo"); 60 | baseTagTwo.InnerText = "default return first tag be found"; 61 | 62 | //quickly get tag from a XmlChildTag 63 | XmlChildTag childB = myXml.GetChildTag("NewRoot", "NewChild"); 64 | XmlBaseTag target = childB.BaseTagList.Where(b => b.Attrs.Keys.Contains("testa")).First(); 65 | target.InnerText = "quickly get combine with lambda let you read write xml file very quick"; 66 | myXml.Save(); 67 | ``` 68 | **`Delete`** is delete the file this XModel Represent. 69 | ```c# 70 | XModel myXml = new XModel("D:\\XML\\", "MyXModel.xml"); 71 | myXml.Delete(); 72 | ``` 73 | 74 | And you can use XModel.ToString() get xml string. you can create a XModel From only XmlTag or xml string, but need set few properties before save to file. 75 | Check it out in the test project. 76 | -------------------------------------------------------------------------------- /src/XmlModel.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XmlModelTest", "XmlModelTest\XmlModelTest.csproj", "{21B8F151-6E89-4CC6-B17E-151C65AEC7D9}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XmlModel", "XmlModel\XmlModel.csproj", "{1DE688E0-00B6-4423-930E-E211FC48A4DC}" 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 | {21B8F151-6E89-4CC6-B17E-151C65AEC7D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {21B8F151-6E89-4CC6-B17E-151C65AEC7D9}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {21B8F151-6E89-4CC6-B17E-151C65AEC7D9}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {21B8F151-6E89-4CC6-B17E-151C65AEC7D9}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {1DE688E0-00B6-4423-930E-E211FC48A4DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {1DE688E0-00B6-4423-930E-E211FC48A4DC}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {1DE688E0-00B6-4423-930E-E211FC48A4DC}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {1DE688E0-00B6-4423-930E-E211FC48A4DC}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /src/XmlModel/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的一般信息由以下 6 | // 控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("XmlModel")] 9 | [assembly: AssemblyDescription("An object mapping to xml file. Quicky CURD xml like object.https://github.com/631320085/XmlModel")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("https://github.com/631320085")] 12 | [assembly: AssemblyProduct("")] 13 | [assembly: AssemblyCopyright("Copyright © CodeFramer 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | //将 ComVisible 设置为 false 将使此程序集中的类型 18 | //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, 19 | //请将此类型的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("1de688e0-00b6-4423-930e-e211fc48a4dc")] 24 | 25 | // 程序集的版本信息由下列四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, 33 | // 方法是按如下所示使用“*”: : 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.1")] 36 | [assembly: AssemblyFileVersion("1.0.0.1")] 37 | -------------------------------------------------------------------------------- /src/XmlModel/XModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.IO; 7 | using System.Xml; 8 | 9 | namespace XmlModel 10 | { 11 | /// 12 | /// Object mapping of a xml file 13 | /// 14 | public class XModel 15 | { 16 | /// 17 | /// Directory of this xml file 18 | /// 19 | public string XmlDirectory { get; set; } 20 | 21 | /// 22 | /// Xml file name 23 | /// 24 | public string FileName { get; set; } 25 | 26 | /// 27 | /// Xml file encode 28 | /// 29 | public string Encode { get; set; } 30 | 31 | /// 32 | /// Root tag 33 | /// 34 | public XmlTag Root { get; set; } 35 | 36 | /// 37 | /// XmlDocument object of this xml file 38 | /// 39 | private XmlDocument XmlDoc { get; set; } 40 | 41 | #region constructor 42 | 43 | /// 44 | /// Default constructor 45 | /// 46 | public XModel() 47 | { 48 | 49 | } 50 | 51 | /// 52 | /// Constructor: Create XmlModel from XmlTag and save xml file 53 | /// 54 | /// directory 55 | /// fileName 56 | /// encode type 57 | /// root tag 58 | public XModel(string directory, string fileName, string encode, XmlTag root) 59 | { 60 | CreateWithFile(directory, fileName, encode, root); 61 | } 62 | 63 | /// 64 | /// Constructor: Create XmlModel from XmlTag only 65 | /// 66 | /// root tag 67 | public XModel(XmlTag root) 68 | { 69 | CreateWithOutFile(root); 70 | } 71 | 72 | /// 73 | /// Constructor: Read XmlModel From xml file 74 | /// 75 | /// directory 76 | /// fileName 77 | public XModel(string directory, string fileName) 78 | { 79 | Read(directory, fileName); 80 | } 81 | 82 | /// 83 | /// Constructor: Read XmlModel From xml string 84 | /// 85 | /// xml string 86 | public XModel(string xml) 87 | { 88 | Read(xml); 89 | } 90 | 91 | #endregion 92 | 93 | #region Create and Read XmlModel 94 | 95 | /// 96 | /// Create XmlModel from XmlTag and save xml file 97 | /// 98 | /// directory 99 | /// fileName 100 | /// encode type 101 | /// root tag 102 | public void CreateWithFile(string directory, string fileName, string encode, XmlTag root) 103 | { 104 | XmlDirectory = directory; 105 | FileName = fileName; 106 | Encode = encode; 107 | Root = root; 108 | Save(); 109 | } 110 | 111 | /// 112 | /// Create XmlModel from XmlTag only 113 | /// 114 | /// 115 | public void CreateWithOutFile(XmlTag root) 116 | { 117 | Root = root; 118 | } 119 | 120 | /// 121 | /// Read XmlModel From xml file 122 | /// 123 | /// directory 124 | /// fileName 125 | public void Read(string directory, string fileName) 126 | { 127 | XmlDirectory = directory; 128 | FileName = fileName; 129 | XmlDoc = new XmlDocument(); 130 | XmlDoc.Load(directory + fileName); 131 | Root = NodeToTag(XmlDoc.DocumentElement); 132 | } 133 | 134 | /// 135 | /// Read XmlModel From xml string 136 | /// 137 | /// xml string 138 | public void Read(string xml) 139 | { 140 | XmlDoc = new XmlDocument(); 141 | XmlDoc.LoadXml(xml); 142 | Root = NodeToTag(XmlDoc.DocumentElement); 143 | } 144 | 145 | #endregion 146 | 147 | /// 148 | /// Get current XmlModel's XmlDocument type object 149 | /// 150 | /// 151 | public XmlDocument GetXmlDocument() 152 | { 153 | //create XmlModel xmldoc is null 154 | if (XmlDoc == null) 155 | { 156 | XmlDoc = new XmlDocument(); 157 | } 158 | //replace root 159 | if (XmlDoc.DocumentElement != null) 160 | { 161 | XmlDoc.RemoveChild(XmlDoc.DocumentElement); 162 | } 163 | XmlDoc.AppendChild(TagToNode(Root)); 164 | //add or edit declaration 165 | if (XmlDoc.FirstChild is XmlDeclaration) 166 | { 167 | if (!string.IsNullOrEmpty(Encode)) 168 | { 169 | (XmlDoc.FirstChild as XmlDeclaration).Encoding = Encode; 170 | } 171 | } 172 | else 173 | { 174 | if (string.IsNullOrEmpty(Encode)) 175 | { 176 | throw new Exception("Encode can't be empty"); 177 | } 178 | XmlDoc.InsertBefore(XmlDoc.CreateXmlDeclaration("1.0", Encode, ""), XmlDoc.FirstChild); 179 | } 180 | return XmlDoc; 181 | } 182 | 183 | /// 184 | /// Save Object to file 185 | /// XmlDirectory and FileName and Encode need to be set before save 186 | /// 187 | public void Save() 188 | { 189 | if(Root == null) 190 | { 191 | throw new Exception("Root can't be null"); 192 | } 193 | if (string.IsNullOrEmpty(XmlDirectory) || string.IsNullOrEmpty(FileName)) 194 | { 195 | throw new Exception("XmlDirectory and FileName need to be set before save"); 196 | } 197 | //generate xmldocument 198 | GetXmlDocument(); 199 | if(!Directory.Exists(XmlDirectory)) 200 | { 201 | Directory.CreateDirectory(XmlDirectory); 202 | } 203 | XmlDoc.Save(XmlDirectory + FileName); 204 | } 205 | 206 | /// 207 | /// Delete file 208 | /// 209 | public void Delete() 210 | { 211 | if(File.Exists(XmlDirectory + FileName)) 212 | { 213 | File.Delete(XmlDirectory + FileName); 214 | } 215 | } 216 | 217 | /// 218 | /// Get xml string 219 | /// 220 | /// 221 | public override string ToString() 222 | { 223 | return GetXmlDocument().OuterXml; 224 | } 225 | 226 | #region Helper 227 | 228 | /// 229 | /// Recurtion transfer XmlNode into XmlTag 230 | /// 231 | /// XmlNode 232 | /// 233 | public XmlTag NodeToTag(XmlNode node) 234 | { 235 | #if false 236 | //不转化注释 237 | for (int i = 0; i < node.ChildNodes.Count; i++) 238 | { 239 | if (node.ChildNodes[i].Name == ("#comment")) 240 | { 241 | node.RemoveChild(node.ChildNodes[i]); 242 | } 243 | } 244 | #endif 245 | //判断当前节点类型返回对应类型节点 246 | if (node.ChildNodes.Count > 0 && node.FirstChild.NodeType != XmlNodeType.Text) 247 | { 248 | XmlChildTag childTag = new XmlChildTag(node.Name); 249 | //属性不为空添加属性 250 | if (node.Attributes != null) 251 | { 252 | foreach (XmlAttribute attr in node.Attributes) 253 | { 254 | childTag.Attrs.Add(attr.Name, attr.Value); 255 | } 256 | } 257 | //递归添加子节点 258 | foreach (XmlNode childNode in node.ChildNodes) 259 | { 260 | XmlTag tag = NodeToTag(childNode); 261 | if(tag is XmlChildTag)//根据子节点类型加入对应列表 262 | { 263 | childTag.ChildTagList.Add(tag as XmlChildTag); 264 | } 265 | else 266 | { 267 | childTag.BaseTagList.Add(tag as XmlBaseTag); 268 | } 269 | } 270 | return childTag; 271 | } 272 | else 273 | { 274 | XmlBaseTag baseTag = new XmlBaseTag((node.NodeType == XmlNodeType.Comment) ? "XMLcomment" : node.Name); 275 | //属性不为空添加属性 276 | if (node.Attributes != null) 277 | { 278 | foreach (XmlAttribute attr in node.Attributes) 279 | { 280 | baseTag.Attrs.Add(attr.Name, attr.Value); 281 | } 282 | } 283 | baseTag.InnerText = node.InnerText; 284 | return baseTag; 285 | } 286 | } 287 | 288 | /// 289 | /// Recurtion transfer XmlTag into XmlNode 290 | /// 291 | /// XmlTag 292 | /// 293 | public XmlNode TagToNode(XmlTag tag) 294 | { 295 | XmlNode node; 296 | if ((tag is XmlBaseTag) && (tag.Name == "XMLcomment")) 297 | { 298 | node = XmlDoc.CreateComment((tag as XmlBaseTag).InnerText); 299 | return node; 300 | } 301 | 302 | node = XmlDoc.CreateElement(tag.Name); 303 | foreach (var attr in tag.Attrs) 304 | { 305 | XmlAttribute xmlAttr = XmlDoc.CreateAttribute(attr.Key); 306 | xmlAttr.Value = attr.Value; 307 | node.Attributes.Append(xmlAttr); 308 | } 309 | if (tag is XmlChildTag) 310 | { 311 | XmlChildTag childTag = tag as XmlChildTag; 312 | if(childTag.BaseTagList.Count == 0 && childTag.ChildTagList.Count == 0) 313 | { 314 | throw new Exception("A XmlChildTag " + childTag.Name + "'s BaseTagList and ChildTagList can't both empty,if this tag don't have any child please use XmlBaseTag type"); 315 | } 316 | //添加对应的子节点 317 | foreach (XmlTag innerTag in childTag.BaseTagList) 318 | { 319 | node.AppendChild(TagToNode(innerTag)); 320 | } 321 | foreach (XmlTag innerTag in childTag.ChildTagList) 322 | { 323 | node.AppendChild(TagToNode(innerTag)); 324 | } 325 | } 326 | else 327 | { 328 | XmlBaseTag baseTag = tag as XmlBaseTag; 329 | node.InnerText = baseTag.InnerText; 330 | } 331 | return node; 332 | } 333 | 334 | /// 335 | /// Quickly get a XmlChildTag 336 | /// 337 | /// tag's name input by order 338 | /// 339 | public XmlChildTag GetChildTag(params string[] tagNames) 340 | { 341 | if(tagNames[0] != Root.Name) 342 | { 343 | throw new Exception("Root tag doesn't match"); 344 | } 345 | if(!(Root is XmlChildTag)) 346 | { 347 | throw new Exception("Root " + tagNames[0] + " must be XmlChildTag type"); 348 | } 349 | XmlChildTag result = Root as XmlChildTag; 350 | for (int i = 1; i < tagNames.Length; i++) 351 | { 352 | if(result.ChildTagList.Where(t => t.Name == tagNames[i]).Count() == 0) 353 | { 354 | throw new Exception("Can't find XmlChildTag tag " + tagNames[i] + " by the input tag names with this order"); 355 | } 356 | result = result.ChildTagList.Where(t => t.Name == tagNames[i]).First(); 357 | } 358 | return result; 359 | } 360 | 361 | /// 362 | /// Quickly get a XmlBaseTag 363 | /// 364 | /// 按顺序输入的节点名称/tag's name input by order 365 | /// 366 | public XmlBaseTag GetBaseTag(params string[] tagNames) 367 | { 368 | if (tagNames[0] != Root.Name) 369 | { 370 | throw new Exception("Root tag doesn't match"); 371 | } 372 | if (Root is XmlBaseTag) 373 | { 374 | if (tagNames.Length == 1) 375 | { 376 | return Root as XmlBaseTag; 377 | } 378 | else 379 | { 380 | throw new Exception("Root " + tagNames[0] + " is XmlBaseTag type, don't have any childs"); 381 | } 382 | } 383 | XmlChildTag ChildTag = Root as XmlChildTag; 384 | for (int i = 1; i < tagNames.Length; i++) 385 | { 386 | if (ChildTag.ChildTagList.Where(t => t.Name == tagNames[i]).Count() == 0 && ChildTag.BaseTagList.Where(t => t.Name == tagNames[i]).Count() == 0) 387 | { 388 | throw new Exception("Can't find XmlTag " + tagNames[i] + " by the input tag names with this order"); 389 | } 390 | //最后一个节点查找BaseTagList,否则查找ChildTagList 391 | if (i == tagNames.Length - 1) 392 | { 393 | if (ChildTag.BaseTagList.Where(t => t.Name == tagNames[i]).Count() > 0) 394 | { 395 | return ChildTag.BaseTagList.Where(t => t.Name == tagNames[i]).First(); 396 | } 397 | else 398 | { 399 | throw new Exception("Tag:" + tagNames[i] + " must be XmlBaseTag type"); 400 | } 401 | } 402 | else 403 | { 404 | //找到对应XmlChildTag节点缩小查找范围 405 | if (ChildTag.ChildTagList.Where(t => t.Name == tagNames[i]).Count() > 0) 406 | { 407 | ChildTag = ChildTag.ChildTagList.Where(t => t.Name == tagNames[i]).First(); 408 | } 409 | else 410 | { 411 | throw new Exception("Tag:" + tagNames[i] + " must be XmlChildTag type"); 412 | } 413 | } 414 | } 415 | return null; 416 | } 417 | 418 | #endregion 419 | } 420 | } 421 | -------------------------------------------------------------------------------- /src/XmlModel/XmlModel.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {1DE688E0-00B6-4423-930E-E211FC48A4DC} 8 | Library 9 | Properties 10 | XmlModel 11 | XmlModel 12 | v4.0 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | bin\Debug\XmlModel.xml 25 | 26 | 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 | 56 | -------------------------------------------------------------------------------- /src/XmlModel/XmlModel.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $id$ 5 | $version$ 6 | $title$ 7 | $author$ 8 | $author$ 9 | https://github.com/631320085/XmlModel 10 | https://github.com/631320085/XmlModel 11 | https://avatars0.githubusercontent.com/u/4160160 12 | false 13 | $description$ 14 | New Release 15 | Copyright 2017 16 | xml xmlmodel Xml XmlModel 17 | 18 | -------------------------------------------------------------------------------- /src/XmlModel/XmlTags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace XmlModel 8 | { 9 | /// 10 | /// XmlTag: A xml tag 11 | /// 12 | public abstract class XmlTag 13 | { 14 | /// 15 | /// Name 16 | /// 17 | public string Name { get; set; } 18 | 19 | /// 20 | /// Attributes 21 | /// 22 | public Dictionary Attrs { get; set; } 23 | } 24 | 25 | /// 26 | /// XmlChildTag: A XmlTag that at least have a XmlChildTag or XmlBaseTag inside 27 | /// 28 | public class XmlChildTag : XmlTag 29 | { 30 | /// 31 | /// XmlChildTags of this XmlChildTag 32 | /// 33 | public List ChildTagList { get; set; } 34 | 35 | /// 36 | /// XmlBaseTags of this XmlChildTag 37 | /// 38 | public List BaseTagList { get; set; } 39 | 40 | /// 41 | /// Constructor 42 | /// 43 | /// Tag's Name 44 | public XmlChildTag(string name) 45 | { 46 | Name = name; 47 | Attrs = new Dictionary(); 48 | ChildTagList = new List(); 49 | BaseTagList = new List(); 50 | } 51 | 52 | /// 53 | /// Get a XmlChildTag from this tag 54 | /// 55 | /// tag's name input by order 56 | /// 57 | public XmlChildTag GetChildTag(params string[] tagNames) 58 | { 59 | XmlChildTag result = this as XmlChildTag; 60 | for (int i = 0; i < tagNames.Length; i++) 61 | { 62 | if (result.ChildTagList.Where(t => t.Name == tagNames[i]).Count() == 0) 63 | { 64 | throw new Exception("Can't find XmlChildTag tag " + tagNames[i] + " by the input tag names with this order"); 65 | } 66 | result = result.ChildTagList.Where(t => t.Name == tagNames[i]).First(); 67 | } 68 | return result; 69 | } 70 | 71 | /// 72 | /// Get a XmlBaseTag from this tag 73 | /// 74 | /// tag's name input by order 75 | /// 76 | public XmlBaseTag GetBaseTag(params string[] tagNames) 77 | { 78 | XmlChildTag ChildTag = this as XmlChildTag; 79 | for (int i = 0; i < tagNames.Length; i++) 80 | { 81 | if (ChildTag.ChildTagList.Where(t => t.Name == tagNames[i]).Count() == 0 && ChildTag.BaseTagList.Where(t => t.Name == tagNames[i]).Count() == 0) 82 | { 83 | throw new Exception("Can't find XmlTag tag " + tagNames[i] + " by the input tag names with this order"); 84 | } 85 | //最后一个节点查找BaseTagList,否则查找ChildTagList 86 | if (i == tagNames.Length - 1) 87 | { 88 | if (ChildTag.BaseTagList.Where(t => t.Name == tagNames[i]).Count() > 0) 89 | { 90 | return ChildTag.BaseTagList.Where(t => t.Name == tagNames[i]).First(); 91 | } 92 | else 93 | { 94 | throw new Exception("Tag:" + tagNames[i] + " must be XmlBaseTag type"); 95 | } 96 | } 97 | else 98 | { 99 | //找到对应XmlChildTag节点缩小查找范围 100 | if (ChildTag.ChildTagList.Where(t => t.Name == tagNames[i]).Count() > 0) 101 | { 102 | ChildTag = ChildTag.ChildTagList.Where(t => t.Name == tagNames[i]).First(); 103 | } 104 | else 105 | { 106 | throw new Exception("Tag:" + tagNames[i] + " must be XmlChildTag type"); 107 | } 108 | } 109 | } 110 | return null; 111 | } 112 | } 113 | 114 | /// 115 | /// Xml基础标签:基础标签内不能有子标签,可以有内部文字 116 | /// XmlBaseTag:XmlBaseTag don't have child tag, but inner text 117 | /// 118 | public class XmlBaseTag : XmlTag 119 | { 120 | /// 121 | /// InnerText 122 | /// 123 | public string InnerText { get; set; } 124 | 125 | /// 126 | /// Constructor 127 | /// 128 | /// Tag's Name 129 | public XmlBaseTag(string name) 130 | { 131 | Name = name; 132 | Attrs = new Dictionary(); 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/XmlModelTest/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/XmlModelTest/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using XmlModel; 7 | 8 | namespace XmlModelTest 9 | { 10 | class Program 11 | { 12 | static void Main(string[] args) 13 | { 14 | /* 15 | * XModel is an object mapping of a xml file 16 | * XModel has two type tag: XmlChildTag and XmlBaseTag 17 | * XmlChildTag must have child tag, means BaseTagList and ChildTagList can't both empty 18 | * XmlBaseTag can't have child tag insie 19 | */ 20 | 21 | while (true) 22 | { 23 | Console.WriteLine("Input a command:"); 24 | switch (Console.ReadLine().ToLower()) 25 | { 26 | case "new": 27 | Create(); 28 | Read(); 29 | Edit(); 30 | QuicklyGet(); 31 | PrintXModel(); 32 | break; 33 | case "delete": 34 | Delete(); 35 | break; 36 | case "nofile": 37 | CreateWithOutFile(); 38 | break; 39 | case "string": 40 | ReadXmlString(); 41 | break; 42 | } 43 | } 44 | } 45 | 46 | //Create a xmlfile 47 | public static void Create() 48 | { 49 | XmlChildTag rootTag = new XmlChildTag("Root"); 50 | rootTag.BaseTagList.Add(new XmlBaseTag("BaseTagOne")); 51 | XModel myXModel = new XModel("D:\\XML\\", "MyXModel.xml", "utf-8", rootTag); 52 | Console.WriteLine("Create success"); 53 | } 54 | 55 | //Read a xml file 56 | public static void Read() 57 | { 58 | XModel myXml = new XModel("D:\\XML\\", "MyXModel.xml"); 59 | string rootName = myXml.Root.Name; 60 | string baseTagOneName = (myXml.Root as XmlChildTag).BaseTagList.First().Name; 61 | Console.WriteLine("Read success"); 62 | } 63 | 64 | //Edit a xml file 65 | public static void Edit() 66 | { 67 | XModel myXml = new XModel("D:\\XML\\", "MyXModel.xml"); 68 | //edit root name and attributes 69 | XmlChildTag root = myXml.Root as XmlChildTag; 70 | root.Name = "NewRoot"; 71 | root.Attrs.Add("attr1", "value1"); 72 | //root add a child tag which have three base tag 73 | XmlChildTag newChild = new XmlChildTag("NewChild"); 74 | newChild.BaseTagList.Add(new XmlBaseTag("BaseTagTwo")); 75 | 76 | XmlBaseTag baseTagThree = new XmlBaseTag("BaseTagThree"); 77 | baseTagThree.Attrs.Add("testa", "testv"); 78 | newChild.BaseTagList.Add(baseTagThree); 79 | 80 | newChild.BaseTagList.Add(new XmlBaseTag("BaseTagFour") { InnerText = "some text" }); 81 | root.ChildTagList.Add(newChild); 82 | //save to file 83 | myXml.Save(); 84 | Console.WriteLine("Edit success"); 85 | } 86 | 87 | //Quickly Get and edit 88 | public static void QuicklyGet() 89 | { 90 | XModel myXml = new XModel("D:\\XML\\", "MyXModel.xml"); 91 | //GetChildTag 92 | XmlChildTag childA = myXml.GetChildTag("NewRoot", "NewChild"); 93 | childA.Attrs.Add("find", "ture"); 94 | 95 | //GetBaseTag 96 | XmlBaseTag baseTagTwo = myXml.GetBaseTag("NewRoot", "NewChild", "BaseTagTwo"); 97 | baseTagTwo.InnerText = "default return first tag be found"; 98 | 99 | //quickly get tag from a XmlChildTag 100 | XmlChildTag childB = myXml.GetChildTag("NewRoot", "NewChild"); 101 | //lambda 102 | XmlBaseTag target = childB.BaseTagList.Where(b => b.Attrs.Keys.Contains("testa")).First(); 103 | target.InnerText = "quickly get combine with lambda let you read write xml file very quick"; 104 | //continue quickly get 105 | XmlBaseTag target2 = childB.GetBaseTag("BaseTagTwo"); 106 | target2.InnerText = "quickly get can be use on XmlChildTag too."; 107 | 108 | myXml.Save(); 109 | Console.WriteLine("QuicklyGet success"); 110 | } 111 | 112 | //Delete 113 | public static void Delete() 114 | { 115 | XModel myXml = new XModel("D:\\XML\\", "MyXModel.xml"); 116 | myXml.Delete(); 117 | Console.WriteLine("Delete success"); 118 | } 119 | 120 | //To string 121 | public static void PrintXModel() 122 | { 123 | XModel myXml = new XModel("D:\\XML\\", "MyXModel.xml"); 124 | Console.WriteLine(myXml.ToString()); 125 | } 126 | 127 | //Create from tag only 128 | public static void CreateWithOutFile() 129 | { 130 | XmlChildTag root = new XmlChildTag("root"); 131 | root.BaseTagList.Add(new XmlBaseTag("base") { InnerText = "test" }); 132 | XModel myXml = new XModel(root); 133 | myXml.XmlDirectory = "d:\\"; 134 | myXml.FileName = "nofile.xml"; 135 | myXml.Encode = "utf-8"; 136 | myXml.Save(); 137 | } 138 | 139 | //Read from xml String 140 | public static void ReadXmlString() 141 | { 142 | XModel newxml = new XModel(new XModel("D:\\XML\\", "MyXModel.xml").ToString()); 143 | newxml.Root.Name = "newroot"; 144 | newxml.XmlDirectory = "d:\\"; 145 | newxml.FileName = "newxml.xml"; 146 | newxml.Encode = "gbk"; 147 | newxml.Save(); 148 | } 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /src/XmlModelTest/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的一般信息由以下 6 | // 控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("XmlModelTest")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("XmlModelTest")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | //将 ComVisible 设置为 false 将使此程序集中的类型 18 | //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, 19 | //请将此类型的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("21b8f151-6e89-4cc6-b17e-151c65aec7d9")] 24 | 25 | // 程序集的版本信息由下列四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, 33 | // 方法是按如下所示使用“*”: : 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/XmlModelTest/XmlModelTest.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {21B8F151-6E89-4CC6-B17E-151C65AEC7D9} 8 | Exe 9 | Properties 10 | XmlModelTest 11 | XmlModelTest 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 | 53 | {1de688e0-00b6-4423-930e-e211fc48a4dc} 54 | XmlModel 55 | 56 | 57 | 58 | 65 | --------------------------------------------------------------------------------