如何使用LINQ从XDocument将XML元素加载到类中(不使用Descendants)

时间:2012-05-03 14:37:41

标签: c# xml linq linq-to-xml

如何使用LINQ从XDocument将XML元素加载到c#类中。我不想使用XDocument.Descendants,因为设置不会重复,只会在XML中出现一次。

这有效,但我认为必须有另一种方法,我不必使用IEnumerable或使用ToArray()并使用第一个元素[0]。有什么建议吗?

CODE

public class BackupItem  // class needed so LINQ reads XML into an editable DbGrid
{
  public bool Backup { get; set; }
  public bool IncludeSubDir { get; set; }
  public string BackupLabel { get; set; }
  public string BackupPath { get; set; }
}

public class BackupSettings  
{
  public bool IncludeDateStamp { get; set; }
  public bool DatePrefix { get; set; }
  public bool DateSuffix { get; set; }
  public string DateFormat { get; set; }
  public bool ZipCompress { get; set; }
  public bool ZipPrefix { get; set; }
  public bool ZipSuffix { get; set; }
  public string ZipText { get; set; }
  public bool BackupToSiblingFolder { get; set; }
  public string SiblingFolder { get; set; }
  public bool BackupToFolder { get; set; }
  public bool IncludeFullPath { get; set; }
  public string BackupFolder { get; set; }
}


  // use a LINQ query to load xml file into datagridview and make datagrid editable (create class with get/set)
  var q = from arg in GvXMLDoc.Descendants("BackupItem")
          select new BackupItem()
          {
            Backup = (bool)arg.Element("IncludeDirectory"),
            IncludeSubDir = (bool)arg.Element("IncludeSubDirectories"),
            BackupLabel = (string)arg.Element("BackupLabel"),
            BackupPath = (string)arg.Element("BackupPath")
          };
  dataGridView1.DataSource = q.ToList();

    // load global variable
    IEnumerable<BackupSettings> GvBackupSettings = from arg in GvXMLDoc.Element("Backup").Elements("Settings")
                                                   select new BackupSettings()
            {
              IncludeDateStamp = (bool)arg.Element("IncludeDateStamp"),
              DatePrefix = (bool)arg.Element("DatePrefix"),
              DateSuffix = (bool)arg.Element("DateSuffix"),
              DateFormat = (string)arg.Element("DateFormat"),
              ZipCompress = (bool)arg.Element("ZipCompress"),
              ZipPrefix = (bool)arg.Element("ZipPrefix"),
              ZipSuffix = (bool)arg.Element("ZipSuffix"),
              ZipText = (string)arg.Element("ZipText"),
              BackupToSiblingFolder = (bool)arg.Element("BackupToSiblingFolder"),
              SiblingFolder = (string)arg.Element("SiblingFolder"),
              BackupToFolder = (bool)arg.Element("BackupToFolder"),
              IncludeFullPath = (bool)arg.Element("IncludeFullPath"),
              BackupFolder = (string)arg.Element("BackupFolder")
            };

我可以访问这些值,但这似乎是一种非常“混乱的方式”。

var s = GvBackupSettings.ToArray()[0].DateSuffix;
var t = GvBackupSettings.ToArray()[0].DateFormat;

XML文件

<?xml version='1.0'?>
<Backup>
  <Settings>
    <IncludeDateStamp>true</IncludeDateStamp>
    <DatePrefix>false</DatePrefix>
    <DateSuffix>true</DateSuffix>
    <DateFormat>yyyy-MM-dd h.m.s</DateFormat>
    <ZipCompress>false</ZipCompress>
    <ZipPrefix>false</ZipPrefix>
    <ZipSuffix>false</ZipSuffix>
    <ZipText></ZipText>
    <BackupToSiblingFolder>true</BackupToSiblingFolder>
    <SiblingFolder>backups</SiblingFolder>
    <BackupToFolder>false</BackupToFolder>
    <IncludeFullPath>true</IncludeFullPath>
    <BackupFolder>C:\\backup</BackupFolder>
  </Settings>
  <BackupItem>
    <IncludeDirectory>true</IncludeDirectory>
    <IncludeSubDirectories>true</IncludeSubDirectories>
    <BackupLabel>Backup1</BackupLabel>
    <BackupPath>C:\TestFiles\Xml\Samples</BackupPath>
  </BackupItem>
  <BackupItem>
    <IncludeDirectory>true</IncludeDirectory>
    <IncludeSubDirectories>false</IncludeSubDirectories>
    <BackupLabel>Backup2</BackupLabel>
    <BackupPath>C:\TestFiles\Xml\Samples</BackupPath>
  </BackupItem>
</Backup>

编辑1 我也试图反序列化XML(感谢你的想法),所以我不必每个项目。这不起作用..我不想也必须运行XSD工具并拥有一个巨大的类文件...

  XmlRootAttribute rootAttribute = new XmlRootAttribute("Backup");
  XmlSerializer deserializer = new XmlSerializer((typeof(BackupSettings)), rootAttribute);
  GvBackupSettings = (BackupSettings)deserializer.Deserialize(XmlReader.Create(GvXMLFileName));

编辑2 使用stardard XSD.exe工具完成下面建议的序列化和反序列化xml以生成c#类。特别是因为我必须读取和写入相同的xml文件。注意:确保首先验证/修改生成的xsd文件。

1 个答案:

答案 0 :(得分:2)

如果您只需要第一个元素,则不需要查询:

XElement settings = GvXMLDoc.Element("Backup").Element("Settings");

BackupSettings GvBackupSettings = new BackupSettings
{
    IncludeDateStamp = (bool)settings.Element("IncludeDateStamp"),
    DatePrefix = (bool)settings.Element("DatePrefix"),
    ...
};

var s = GvBackupSettings.DateSuffix;
var t = GvBackupSettings.DateFormat;