Как я могу условно выписать XML менее подробным способом? - PullRequest
4 голосов
/ 29 марта 2012

Я хочу написать XML-файл с C #. Это основной файл, подобный этому:

<EmployeeConfiguration>
  <Bosses>
    <Boss name="BOB">
      <Employees>
        <Employee Id="#0001" />
        <Employee Id="#0002" />
      </Employees>
    <Boss>
  </Bosses>
</EmployeeConfiguration>

и я не хочу иметь узел Employees, если нет узла Employee ...

Я хочу использовать XElement, но не могу из-за этого ... Поэтому я использовал XmlWriter. он отлично работает, но я считаю, что писать XML очень многословно:

EmployeeConfiguration config = EmployeeConfiguration.GetConfiguration();

using (XmlWriter writer = XmlWriter.Create(_fileUri, settings))
{
  writer.WriteStartDocument();

  // <EmployeeConfiguration>
  writer.WriteStartElement("EmployeeConfiguration");

  if (config.Bosses.Count > 0)
  {
    // <Bosses>
    writer.WriteStartElement("Bosses");

    foreach (Boss b in config.Bosses)
    {
      // Boss
      writer.WriteStartElement("Boss");
      writer.WriteStartAttribute("name");
      writer.WriteString(b.Name);
      writer.WriteEndAttribute();

      if (b.Employees.Count > 0)
      {
        writer.WriteStartElement("Employees");

        foreach (Employee emp in b.Employees)
        {
            writer.WriteStartElement(Employee);
            writer.WriteStartAttribute(Id);
            writer.WriteString(emp.Id);
            writer.WriteEndAttribute();
            writer.WriteEndElement();
        }
      }
    }
  }
}

Есть ли другой (и самый быстрый) способ написания такого типа XML-файла?

Ответы [ 3 ]

6 голосов
/ 29 марта 2012

Если вы имеете в виду «самый быстрый» как самый быстрый способ написания некоторого кода для его выполнения (и самый простой), то тогда вам нужно создать собственный класс и сериализовать его с помощью XmlSerializer . .

Создайте свои классы следующим образом:

[XmlRoot("EmployeeConfiguration")]
public class EmployeeConfiguration
{
    [XmlArray("Bosses")]
    [XmlArrayItem("Boss")]
    public List<Boss> Bosses { get; set; }
}

public class Boss
{
    [XmlAttribute("name")]
    public string Name { get; set; }

    [XmlArray("Employees")]
    [XmlArrayItem("Employee")]
    public List<Employee> Employees { get; set; }
}

public class Employee
{
    [XmlAttribute]
    public string Id { get; set; }
}

и затем вы можете сериализовать их так:

// create a serializer for the root type above
var serializer = new XmlSerializer(typeof (EmployeeConfiguration));

// by default, the serializer will write out the "xsi" and "xsd" namespaces to any output.
// you don't want these, so this will inhibit it.
var namespaces = new XmlSerializerNamespaces(new [] { new XmlQualifiedName("", "") });

// serialize to stream or writer
serializer.Serialize(outputStreamOrWriter, config, namespaces);

Как видите, использование различных атрибутов в классах указывает сериализатору, как он должен сериализовать класс. Некоторые из тех, что я включил выше, на самом деле являются настройками по умолчанию, и их явно не нужно указывать - но я включил их, чтобы показать вам, как это делается.

1 голос
/ 29 марта 2012
var xml =  new XElement("EmployeeConfiguration", 
                        new XElement("Bosses"),                           
                         new XElement("Boss", new XAttribute("name", "BOB"),
                           new XElement("Employees"),
                            new XElement("Employee", new XAttribute("Id", "#0001")),
                            new XElement("Employee", new XAttribute("Id", "#0001"))
                    )
                );
1 голос
/ 29 марта 2012

Возможно, вы захотите взглянуть на сериализацию XML, используя атрибуты XmlElement, XmlAttribute (и т. Д.). Я думаю, что это дает вам необходимый уровень контроля и очень быстрый, безопасный и простой в обслуживании вызов для преобразования XML.

...