以下是我写的通过读取xml文件,生成DataModel类的.cs文件的一个方法。
写的比较乱。
做一个备份,省得以后需要再写。
尤其对于比较大的Config文件需要生成datamodel时,比较省力气。
序列化和反序列化是通过XmlXXX系列的属性类实现的。
每个xml文档的节点对应一个类,类的结构和xml的结构类似,是嵌套的。
为防止类名和变量名冲突,类名的创建规则:“C” + 【节点名】。
代码:
public static string GenerateCSClass()
{
string path = _filePath; // xml 文件路径
string nameSpace = _nameSpace; // 待创建文件中类所在的名字空间
string output = ReadDocAndCreateClass(path, nameSpace);
return output;
}
public static string ReadDocAndCreateClass(string configFilePath, string nameSpace)
{
XmlDocument doc = new XmlDocument();
doc.Load(configFilePath);
XmlElement root = doc.DocumentElement;
_rootName = root.Name;
string format_1 = @"using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.Xml;
namespace " + nameSpace+ @"
{ " + LRLN
+ "[Serializable]" + LRLN
+ "[XmlRoot(_rootName)]" + LRLN; // _rootName是xml文件中的根节点的名字
string format_2 = @"
}";
string fill = CreateClass(root, false);
string output = format_1 + fill + format_2;
return output;
}
public static string CreateClass(XmlElement element, bool b)
{
string section = string.Empty;
string name = element.Name;
bool bt = false;
if (name.Contains("-"))
{
bt = true;
name = name.Replace('-', '_');
}
else
{
bt = false;
}
string newName = name;
while (classList.Contains(newName))
{
newName = element.ParentNode.Name + newName;
}
classList.Add(newName);
if (element.HasChildNodes && element.ChildNodes.Count > 0)
{
section = "public class C" + newName + LRLN
+ "{" + LRLN;
if (element.Attributes != null && element.Attributes.Count > 0)
{
string output = string.Empty;
for (int i = 0; i < element.Attributes.Count; i++)
{
output += "[XmlAttribute]" + LRLN
+ "public string " + element.Attributes[i].Name + ";";
output += LRLN;
section += output;
}
}
List<int> all = new List<int>();
List<int> redundant = new List<int>();
XmlNodeList nodes = element.ChildNodes;
//for (int i = 0; i < nodes.Count; i++)
//{
for (int m = 0; m < nodes.Count; m++)
{
if (!(nodes[m] is XmlElement))
continue;
if (!all.Contains(m) && !redundant.Contains(m))
all.Add(m);
else
continue;
for (int n = m + 1; n < nodes.Count; n++)
{
if (nodes[m].Name == nodes[n].Name)
{
if (!all.Contains(n))
redundant.Add(n);
if (!redundant.Contains(m))
redundant.Add(m);
}
}
}
//}
//bool cc = false;
int count = 0;
for (int i = 0; i < nodes.Count; i++)
{
if (nodes[i] is XmlText)
{
if (nodes[i].InnerText.Trim() == string.Empty)
continue;
string Value = "Value";
for (int x = 0; x < nodes.Count; x++)
{
if (x == i)
continue;
if (Value == nodes[x].Name)
{
Value += Value;
x = 0;
}
}
for (int y = 0; y < count; y++)
{
Value += Value;
}
section += "[XmlText]" + LRLN
+ "public string " + Value + ";" + LRLN;
count++;
}
if (!(nodes[i] is XmlElement))
continue;
bool bb = all.Contains(i);
bool cc = redundant.Contains(i);
if (bb)
{
string output = CreateClass((XmlElement)nodes[i], cc);
if (i + 1 < nodes.Count)
{
output += LRLN;
}
section += output;
}
}
section += LRLN
+ "}" + LRLN;
if (name != _rootName)
{
section += (b || bt ? "[XmlElement" + (bt ? "(/"" + element.Name + "/")" : string.Empty) + "]" + LRLN : string.Empty)
+ "public C" + newName + (b ? "[]" : string.Empty) + SPACE + name + ";" + LRLN2;
}
}
else
{
section += "public class C" + newName + LRLN
+ "{" + LRLN
+ "[XmlText]" + LRLN
+ "public string Value;" + LRLN
+ "}" + LRLN
+ (bt ? "[XmlElement" + (bt ? "(/"" + element.Name + "/")" : string.Empty) + "]" + LRLN : string.Empty)
+ "public C" + newName + " " + newName + ";" + LRLN;
//}
}
return section;
}