簡體   English   中英

從文本文檔在C#中創建XML層次結構

[英]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。
隨意更改標簽的命名方式,這是我需要做的主要事情:

  1. 能夠獲得由同一個人監督的每個人的姓名。 (例如:馬克會想要馬克和安)

  2. 能夠獲得員工之上的所有主管的姓名(例如:Mark是Bob和Jill)

  3. 能夠獲得當時所有人的姓名(例如:馬克將沒有任何人,吉爾將擁有所有人,鮑勃將擁有馬克和安)

我看過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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM