[英]Create XML Hierarchy in C# from Text Doc
我需要从服务器中获取一个文本文档,并从中创建一个XML层次结构,以便在C#程序中使用它。
这将是一个组织层次结构。 这与文本文件相同:
EmployeeID; Employee Name; SupervisorID
1; Bob; 3
2; Mark; 1
3; Jill; 0
4; Ann ; 1
以上关系将是:
鲍勃的老板是吉尔。 马克的老板是鲍勃,而吉尔没有老板。
我想从该数据创建一个XML文件,如下所示:
<Employee> Jill
<Employee> Bob
<Employee> Mark </Employee>
<Employee> Ann </Employee>
</Employee>
</Employee>
我不知道这是否有意义,因为我以前从未使用过C#或XML。
随意更改标签的命名方式,这是我需要做的主要事情:
能够获得由同一个人监督的每个人的姓名。 (例如:马克会想要马克和安)
能够获得员工之上的所有主管的姓名(例如:Mark是Bob和Jill)
能够获得当时所有人的姓名(例如:马克将没有任何人,吉尔将拥有所有人,鲍勃将拥有马克和安)
我看过XElement和XDoc以及各种教程和SO问题,但目前大多数SO问题对我来说太高级了,并且大多数教程都没有尝试创建像我这样的层次结构。
定义一个Employee类:
public class Employee{
[XmlIgnore]
public int ID{get;set;}
[XmlIgnore]
public int BossID{get;set;}
[XmlText]
public string Name{get;set;}
[XmlElement("Employee")
public Employee[] Minions{get;set;}
public SetMinions(List<Employee> list){
Minions = list.Where(e=>e.BossID==ID).ToArray();
}
}
然后解析您的输入:
List<Employee> list = File.ReadAllLines("MyInputFile.txt")
.Select(l=>new Emplyee(){
ID = l.Split(';')[0],
Name= l.Split(';')[1],
BossID = l.Split(';')[2]}).ToList();
然后为每个设置奴才:
list.ForEach(e=>e.SetMinions(list));
并生成如下所示的XML:
XmlSerializer xser = new XmlSerializer(typeof(Employee));
xser.Serialize(File.OpenWrite("output.txt", list.First(e=>e.BossID==0)));
如果不太明显,则此代码很脏且不可靠,请添加一些检查和清理
Employee
类别:
public class Employee
{
public Employee()
{
Subordinates = new List<Employee>();
}
public int Id { get; set; }
public string Name { get; set; }
public int SupervisorId { get; set; }
public List<Employee> Subordinates { get; private set; }
public XElement ToXml()
{
return new XElement("Employee",
new XElement("Id", Id),
new XElement("Name", Name),
new XElement("Subordinates", Subordinates.Select(s => s.ToXml())));
}
}
并解析逻辑:
// dictionary as a storage for data read from file
var Employees = new Dictionary<int,Employee>();
// file reading
var file = File.Open("Input.txt", FileMode.Open);
using (var reader = new StreamReader(file))
{
reader.ReadLine();
while (!reader.EndOfStream)
{
string line = reader.ReadLine();
string[] fields = line.Split(';');
var newEmployee = new Employee { Id = int.Parse(fields[0]), Name = fields[1].Trim(), SupervisorId = int.Parse(fields[2]) };
Employees.Add(newEmployee.Id, newEmployee);
}
}
// filling Subordinates within every employee
foreach (var emp in Employees.Values)
{
if (Employees.ContainsKey(emp.SupervisorId))
Employees[emp.SupervisorId].Subordinates.Add(emp);
}
// taking first (root) employee by selecting the one with supervisorId == 0
var first = Employees.Values.First(e => e.SupervisorId == 0);
// XML generation
var xml = first.ToXml();
我从该代码收到的结果连同您的示例输入:
<Employee>
<Id>3</Id>
<Name>Jill</Name>
<Subordinates>
<Employee>
<Id>1</Id>
<Name>Bob</Name>
<Subordinates>
<Employee>
<Id>2</Id>
<Name>Mark</Name>
<Subordinates />
</Employee>
<Employee>
<Id>4</Id>
<Name>Ann</Name>
<Subordinates />
</Employee>
</Subordinates>
</Employee>
</Subordinates>
</Employee>
我认为这种结构比您建议的要好。 但是,您可以通过修改Employee
类中的ToXml
方法来轻松地修改XML结构。 以下是您建议的输出:
public XElement ToXml()
{
return new XElement("Employee",
new XText(Name),
Subordinates.Select(s => s.ToXml()));
}
结果:
<Employee>Jill
<Employee>Bob
<Employee>Mark</Employee>
<Employee>Ann</Employee>
</Employee>
</Employee>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.