在c#中从文本文档创建XML层次结构

本文关键字:创建 XML 层次结构 文档 文本 | 更新日期: 2023-09-27 18:01:42

我需要从服务器获取文本文档,并从中创建XML层次结构,以便在c#程序中使用它。

它将是一个组织层次结构。下面是相同的文本文件:

EmployeeID; Employee Name; SupervisorID
1; Bob; 3
2; Mark; 1
3; Jill; 0
4; Ann ; 1

以上关系为:

鲍勃的老板是吉尔。Mark的老板是Bob,而Jill没有老板。

我想创建一个XML文件从这些数据看起来像这样:

<Employee> Jill
   <Employee> Bob
      <Employee> Mark </Employee>
      <Employee> Ann </Employee>
  </Employee>
</Employee>

我不知道这是否有意义,因为我以前从未使用过c#或XML。
可以随意更改标签的命名方式,我需要做的主要事情是:

  1. 能够得到同一个人监督的每个人的名字。(例如:Mark想要Mark和Ann)

  2. 能够获得员工以上所有主管的名字(例如:Mark的名字是Bob和Jill)

  3. 能够得到所有人的名字(例如:Mark没有人,Jill有所有人,Bob有Mark和Ann)

我看过XElement和XDoc以及各种教程和SO问题,但大多数SO问题对我来说都太高级了,而且大多数教程都没有尝试创建像我这样的层次结构。

在c#中从文本文档创建XML层次结构

定义一个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 class:

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>