读取XML文件并创建与XML内容匹配的对象列表

本文关键字:XML 对象 列表 文件 创建 读取 | 更新日期: 2023-09-27 18:20:49

我有一个XML文件,其中包含一些关于在特定计算机上安装了哪些组件以及属于每个组件的配置文件的信息。

该文件的开发示例如下:

<?xml version="1.0" encoding="utf-8"?>
<ConfigMappings>
  <Host Name="Host1">
    <Component Name="AlarmManager" Version="1.0.1.0" Enabled="True">
      <Config Name="AlarmManager.Configuration.xml" Version="1.0.0.0" SubFolder=""/>
      <Config Name="faultMapConfig.xml" Version="1.0.0.0" SubFolder=""/>
      <Config Name="LoadsCalculatorConfig.xml" Version="1.0.0.0" SubFolder="Advisory"/>
    </Component>
  </Host>
<Host Name="Host2">
    <Component Name="AdvisoryManager" Version="1.0.1.0" Enabled="True">
      <Config Name="DeviceManager.Configuration.xml" Version="1.0.0.1" SubFolder=""/>
      <Config Name="BasicData.xml" Version="1.0.0.2" SubFolder="Advisory"/>
      <Config Name="BasicData.xsd" Version="1.0.0.3" SubFolder="Advisory"/>
      <Config Name="Utilization.xml" Version="1.0.0.4" SubFolder=""/>
      <Config Name="Utilization.xsd" Version="1.0.0.4" SubFolder=""/>
      <Config Name="faultMapConfig.xsd" Version="1.0.0.4" SubFolder=""/>
      <Config Name="faultMapConfig.xml" Version="1.0.0.4" SubFolder=""/>
    </Component>
    <Component Name="w32time" Version="1.0.1.0" Enabled="True">
       <Config Name="DeviceManager.Configuration.xml" Version="1.0.0.1" SubFolder=""/>
    </Component>
  </Host>    
</ConfigMappings>

我想做的是读取这个XML文件,并在其中找到与我的计算机主机名匹配的Host元素。我想创建一个包含名称、版本和已启用属性的组件列表+其配置(名称、版本、子文件夹)的列表。

我通过自己的努力做到了这一点:

var xdoc = XDocument.Load(dlg.FileName);
var components =
    from c in xdoc.Descendants("Component")
    where
        String.Equals(c.Parent.Attribute("Name").Value, Environment.MachineName, StringComparison.CurrentCultureIgnoreCase)
    select new
    {
        Name = c.Attribute("Name").Value,
        Enabled = c.Attribute("Enabled").Value,
        version = c.Attribute("Version").Value,
    };
ComponentList.Clear();
foreach (var component in components)
{
    bool componentEnable = component != null && component.Enabled == "True";
    ComponentList.Add(new Component(component.Name, componentEnable, component.version));
}
foreach (var component in ComponentList)
{
    var configs =
    from c in xdoc.Descendants("Config")
    where 
    c.Parent.Parent.Name == "Host" &&
    String.Equals(c.Parent.Parent.Attribute("Name").Value, Environment.MachineName, StringComparison.CurrentCultureIgnoreCase) &&
    String.Equals(c.Parent.Attribute("Name").Value, component.Name, StringComparison.CurrentCultureIgnoreCase)
    select new
    {
        Name = c.Attribute("Name").Value,
        version = c.Attribute("Version").Value,
        SubFolder = c.Attribute("SubFolder").Value,
    };
    foreach (var config in configs)
    {
        component.Configurations.Add(new Config(config.Name, config.version, config.SubFolder));
    }
}

这里的ComponentList是一个组件列表。Component是一个类,包含其属性(Name、Version和Enabled)+配置对象列表。

现在这就行了。但这似乎是一种非常混乱和混乱的方式,我希望得到一些帮助来改善这一点。

读取XML文件并创建与XML内容匹配的对象列表

namespace ConsoleApplication3
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Net;
    using System.Text;
    using System.Threading.Tasks;
    using System.Xml.Linq;
 public class Config
        {
            public string Name { get; set; }
            public string Version { get; set; }
            public string SubFolder { get; set; }
        }
    public class Component
    {
        public List<Config> SystemConfig;
        public string Name { get; set; }
        public string Version { get; set; }
        public string Enabled { get; set; }
        public Component()
        {
            this.SystemConfig = new List<Config>();
        }
    }
    public class Program
    {
        public static void Main()
        {
            XDocument xmlDocument = XDocument.Load(@"c:'Visual Studio'Projects'ConsoleApplication3'ConsoleApplication3'config.xml");
            var item = (from template in xmlDocument.Descendants("Component")
                        where template.Parent.Attribute("Name").Value.Equals("Host1", StringComparison.CurrentCultureIgnoreCase)
                        select new Component()
                        {
                            Version = template.Attribute("Version").Value,
                            Name = template.Attribute("Name").Value,
                            Enabled = template.Attribute("Enabled").Value,
                            SystemConfig = (
                               from t in template.Elements("Config")
                               select new Config()
                               {
                                   Name = t.Attribute("Name").Value,
                                   SubFolder = t.Attribute("SubFolder").Value,
                                   Version = t.Attribute("Version").Value
                               }
                               ).ToList()
                        }
                                 ).FirstOrDefault();
        }
    }
}

请随意删除硬编码值。上面的代码将为您提供主机名匹配的第一个对象。

不确定这是否有帮助,但为了阅读XML,我通常使用这样的代码:

XmlDocument doc = new XmlDocument();
doc.Load(pathOfYourXmlDocument);

然后你可以做这样的事情:

XmlElement root= doc["ConfigMappings"];

然后你可以选择其他节点,如下所示:

XmlNode host= root.SelectSingleNode("Host1"); 
XmlNode component = host.SelectSingleNode("Component");

最后创建一个组件所有子节点的列表,如下所示:

XmlNodeList configList = component.SelectNodes("Config");

现在,您可以通过XmlNodeList进行迭代,并获得Innertexts、Attributes或任何您需要的内容。不确定这是否对你有帮助,显然没有对错之分,只有不同的解决方案,有些可能很漂亮,有些可能有效,有些可能两者兼而有之。这是我读取Xml文件并使用它们的方式,但还有更多的可能性。

如果你有POCO,那么你可以写(注意字符串扩展到反序列化xml(源)):

ConfigMappings item;
if(File.ReadAllText(@"d:'in.csv").Deserialize(out item)){
  //item is loaded
}

要获得POCO副本&将特殊-粘贴为xml类(最小VS2012.2 RC)。

[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class ConfigMappings {
    [System.Xml.Serialization.XmlElementAttribute("Host")]
    public ConfigMappingsHost[] Host { get; set; }
}
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class ConfigMappingsHost {
    [System.Xml.Serialization.XmlElementAttribute("Component")]
    public ConfigMappingsHostComponent[] Component { get; set; }
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string Name { get; set; }
}
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class ConfigMappingsHostComponent {
    [System.Xml.Serialization.XmlElementAttribute("Config")]
    public ConfigMappingsHostComponentConfig[] Config { get; set; }
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string Name { get; set; }
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string Version { get; set; }
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string Enabled { get; set; }
}
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class ConfigMappingsHostComponentConfig {
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string Name { get; set; }
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string Version { get; set; }
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string SubFolder { get; set; }
}