C#访问xml,一般有两种方式:序列化/反序列化,或者直接访问xml节点。对一个第三方的xml文件进行读写,序列化反序列的方式不好用,因为我们往往只会使用部分的xml节点,反序列化容易破坏原来xml文件的结构。直接访问xml节点能解决问题,但是会写很多的代码。Castle.Core为我们提供了一个优雅的解决方案,下面是一个简单的示例。
1、新建config.xml文件
<?xml version="1.0" encoding="utf-8" ?>
<config>
<UserName>小明</UserName>
<ServerIPAddress>127.0.0.1</ServerIPAddress>
<Numbers>
<int>1</int>
<int>2</int>
</Numbers>
</config>
2、新建IConfig接口
public interface Config
{
string UserName { get; set; }
[XPath("ServerIPAddress")]
string IPAddress { get; set; }
IList<int> Numbers { get; }// 数组、BindingList都支持
[XPath("sum(Numbers)")]// xpath函数
int Sum { get; }
}
3、测试代码
static void Main(string[] args)
{
// 创建数据适配器,通过类名可以发现他不光是可以处理xml
DictionaryAdapterFactory factory = new DictionaryAdapterFactory();
// 加载xml
XmlDocument xml = new XmlDocument();
xml.Load("config.xml");
// 获取操作xml的代理对象
Config config = factory.GetAdapter<Config>(xml);
Console.WriteLine("UserName : " + config.UserName);
Console.WriteLine("IPAddress : " + config.IPAddress);
Console.WriteLine("Numbers : " + string.Join(", ", config.Numbers));
Console.WriteLine("Sum : " + config.Sum);
// 修改数据
config.UserName = "张三";
config.Numbers.Add(666);
// 保存数据
xml.Save("output.xml");
Console.ReadLine();
}
4、输出
控制台:
UserName : 小明
IPAddress : 127.0.0.1
Numbers : 1, 2
Sum : 12
output.xml:
<?xml version="1.0" encoding="utf-8"?>
<config>
<UserName>张三</UserName>
<ServerIPAddress>127.0.0.1</ServerIPAddress>
<Numbers>
<int>1</int>
<int>2</int>
<int>666</int>
</Numbers>
</config>
Castle.Core会根用户定义的接口,通过Emit的方式动态生成一个操作xml的代理类型。除了上面的示例,它还支持嵌套的复制类型,访问xml属性,设置名称空间等大多数对xml的访问需求。