无法弄清楚如何使用Linq to XML来有条件地添加节点?

时间:2016-06-28 16:56:09

标签: c# xml linq

我尝试使用Linq to XML从员工列表中创建一个文件,该员工列表中还包含与其关联的组列表。但是,我还必须对这些组进行一些条件检查。我有一些代码可以创建员工,但我不知道如何遍历组并有条件地添加元素。

以下是如何格式化XML的示例。他们希望每个员工有一个节点具有多个属性。然后是员工下面与他们关联的每个组的节点。这就是我遇到问题的部分。

<CXIXML>
  <Directives>
    <Updates>
      <Emp tasEmpID="00123" lName="Doe" fName="John" empStatus="A" classification="S" />
      <Group groupId="1">
      <Group groupId="5">
      <Group groupId="12">
      <Emp tasEmpID="00456" lName="Smith" fName="Jane" empStatus="A" classification="S" />
      <Group groupId="1">
    </Updates>
  </Directives>
</CXIXML>

以下是我目前如何使用Linq to XML创建员工档案。这是有效的,我最初的想法是创建员工XML文件,然后循环回员工列表,根据属性中的ID找到员工节点,查找他们所在的组,然后添加组节点。

我觉得必须有一种更简单的方法来做到这一点,特别是因为除了每个员工对象已经拥有他们在ClockGroup列表中关联的组之外,我还需要创建员工。

public class Employee
{
    public string EmployeeId { get; set; }
    public string AdminEnrollFlag { get; set; }
    public string EmployeeLastName { get; set; }
    public string EmployeeFirstName { get; set; }
    public string EmployeeWorkStat { get; set; }
    public string EmployeeCo { get; set; }

    public List<GroupAssociation> ClockGroup { get; set; }
}

public class GroupAssociation
{
    public int emp_id { get; set; }
    public int group_id { get; set; }
}


private static void CreateExportFile(List<Employee> fileEmployees, string fileCount)
{
    string fileLocation = ConfigurationManager.AppSettings["FileLocation"];

    XDocument xmlDoc = new XDocument(
        new XDeclaration("1.0", "utf-8", "yes"),
        new XElement("CXIXML",
            new XElement("Directives",
            new XElement("Updates",
                from emp in fileEmployees
                select new XElement("Emp",
                                    new XAttribute("tasEmpID", emp.EmployeeId.PadLeft(8, '0')),
                                    new XAttribute("lName", emp.EmployeeLastName),
                                    new XAttribute("fName", emp.EmployeeFirstName),                                 
                                    new XAttribute("empStatus", SetWorkStat(emp.EmployeeWorkStat)),
                                    new XAttribute("classification", SetClassification(emp.AdminWebAccess, emp.AdminEnrollFlag))))))
    );


    string formatedDate = System.DateTime.Now.ToString("yyyyMMdd_hhmm_");
    string filePath = fileLocation + "VTC_" + formatedDate + fileCount.PadLeft(3, '0') + ".xml";
    xmlDoc.Save(filePath);
}


<CXIXML>
  <Directives>
    <Updates>
      <Emp tasEmpID="00123" lName="Doe" fName="John" empStatus="A" classification="S" />
      <Emp tasEmpID="00456" lName="Smith" fName="Jane" empStatus="A" classification="S" />
    </Updates>
  </Directives>
</CXIXML>

所以,这里是群组的踢球者。我有一些条件来看待这些团体。如果有0个组关联,我必须写出一个节点,其中groupId是一个特定的数字(例如:GroupId = 2表示没有组关联)。我还必须查看他们是否具有Admin访问权限,如果是,他们有一个特定的groupId(例如:GroupId = 1),否则我必须写出所有组。

您认为这可以通过Linq to XML完成吗?或者,我应该使用XmlDocument基于我的List写出节点吗?

1 个答案:

答案 0 :(得分:1)

您可以使用与XDocument非常相似的方式使用XmlDocument,因此您无需更改此内容。

我可能会这样做:

var employeeUpdates = fileEmployees.SelectMany(CreateEmployeeElements);

XDocument doc = new XDocument(
    new XDeclaration("1.0", "utf-8", "yes"),
    new XElement("CXIXML",
        new XElement("Directives",
            new XElement("Updates", employeeUpdates)
        )
    )
);

并且CreateEmployeeElements可以为每个员工返回尽可能多的元素(我遗漏了大部分细节):

private static IEnumerable<XElement> CreateEmployeeElements(Employee employee)
{
    yield return new XElement("Emp", /* content */);

    if (employee.ClockGroup.Count == 0)
    {
        yield return new XElement("Group", new XAttribute("groupId", 2));
    }

    // and so on for more element conditions
}