我有一个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元素。我想创建一个包含Name,Version和Enabled属性的组件列表+其Configs列表(Name,Version,Subfolder)。
我已经成功实现了这一目标:
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)+配置对象列表的类。
现在这个有效。但这似乎是一种非常混乱和混乱的方式,我想要一些帮助来改善这一点。
答案 0 :(得分:0)
不确定这是否有帮助但是读取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文件并使用它们的方式,但还有更多的可能性。
答案 1 :(得分:0)
如果您有POCO,那么您可以编写(注意字符串扩展以反序列化xml(source)):
ConfigMappings item;
if(File.ReadAllText(@"d:\in.csv").Deserialize(out item)){
//item is loaded
}
获取POCO copy &amp; 将特殊的 - 粘贴为xml类(min 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; }
}
答案 2 :(得分:0)
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();
}
}
}
请随时删除硬编码值。上面的代码将为您提供第一个匹配主机名的对象。