xml基本操作

在实际项目中遇到一些关于xml操作的问题,被逼到无路可退的时候终于决定好好研究xml一番。xml是一种可扩展标记语言,可跨平台进行传输,因此xml被广泛的使用在很多地方。

本文由浅入深,首先就xml的基本操作增删改查进行简单介绍,接着对最近公司里面的一个项目中所涉及到xml的一些基本应用加以说明,最后介绍到xml不经常使用的命名空间问题,都是一些关于xml最基本的应用,本文在这里只是记录,以备以后查阅。

 

xml常用方法:

定义xml文档:XmlDocument xmlDoc = new XmlDocument();
初始化xml文档:xmlDoc.Load("D:\\book.xml");//找到xml文件
创建根元素:XmlElement xmlElement = xmlDoc.CreateElement("", "Employees", "");
创建节点:XmlElement xeSub1 = xmlDoc.CreateElement("title");
查找Employees节点:XmlNode root = xmlDoc.SelectSingleNode("Employees");
添加节点:xe1.AppendChild(xeSub1);
更改节点的属性:xe.SetAttribute("Name", "李明明");
移除xe的ID属性:xe.RemoveAttribute("ID");
删除节点title:xe.RemoveChild(xe2);

 

1 创建xml文档

因为比较简单,直接写方法及结果。

public void CreateXMLDocument()
        {
            XmlDocument xmlDoc = new XmlDocument();           

//加入XML的声明段落,<?xml version="1.0" encoding="gb2312"?>
            XmlDeclaration xmlDeclar;
            xmlDeclar = xmlDoc.CreateXmlDeclaration("1.0", "gb2312", null);
            xmlDoc.AppendChild(xmlDeclar);           

//加入Employees根元素
            XmlElement xmlElement = xmlDoc.CreateElement("", "Employees", "");
            xmlDoc.AppendChild(xmlElement);         

//添加节点
            XmlNode root = xmlDoc.SelectSingleNode("Employees");
            XmlElement xe1 = xmlDoc.CreateElement("Node");
            xe1.SetAttribute("Name", "李明");
            xe1.SetAttribute("ISB", "2-3631-4");         

//添加子节点
            XmlElement xeSub1 = xmlDoc.CreateElement("title");
            xeSub1.InnerText = "学习VS";
            xe1.AppendChild(xeSub1);

            XmlElement xeSub2 = xmlDoc.CreateElement("price");
            xe1.AppendChild(xeSub2);
            XmlElement xeSub3 = xmlDoc.CreateElement("weight");
            xeSub3.InnerText = "20";
            xeSub2.AppendChild(xeSub3);


            root.AppendChild(xe1);
            xmlDoc.Save("D:\\book.xml");//保存的路径
        }
View Code

 

结果:

<?xml version="1.0" encoding="GB2312"?>
-<Employees>-
  <Node ISB="2-3631-4" Name="李明">
    <title>学习VS</title>-
    <price>
      <weight>20</weight>
    </price>
  </Node>
</Employees>

 

2 增加节点

XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load("D:\\book.xml");//找到xml文件
            XmlNode root = xmlDoc.SelectSingleNode("Employees");//查找Employees节点
            XmlElement xe1 = xmlDoc.CreateElement("Node2");//添加Node2节点
            xe1.SetAttribute("Name", "张三");
            XmlElement xeSub1 = xmlDoc.CreateElement("title");//定义子节点
            xeSub1.InnerText = "心情好";
            xe1.AppendChild(xeSub1);//添加节点到Node2
            root.AppendChild(xe1);//添加节点到Employees
            xmlDoc.Save("D:\\book.xml");

 

结果:

<?xml version="1.0" encoding="GB2312"?>
  -<Employees>
    -<Node ISB="2-3631-4" Name="李明">
      <title>学习VS</title>-
      <price>
        <weight>20</weight>
      </price>
    </Node>-
    <Node2 Name="张三">
      <title>心情好</title>
    </Node2>-
    <Node2 Name="张三">
      <title>心情好</title>
    </Node2>
</Employees>

 

3 修改节点:

public void ModifyNode()
        {
            XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.Load("D:\\book.xml");

            XmlNodeList nodeList = xmlDocument.SelectSingleNode("Employees").ChildNodes;//获取Employees节点的所有子节点

            foreach (XmlNode xn in nodeList)//遍历
            {
                XmlElement xe = (XmlElement)xn;
                if (xe.GetAttribute("Name") == "李明")
                {
                    xe.SetAttribute("Name", "李明明");//更改节点的属性

                    XmlNodeList xnl = xe.ChildNodes;//获取xe的所有子节点
                    foreach (XmlNode xn1 in xnl)
                    {
                        XmlElement xe2 = (XmlElement)xn1;//将节点xn1的属性转换为XmlElement
                        if (xe2.Name == "title")//找到节点名字为title的节点
                        {
                            xe2.InnerText = "今天天气不好";
                        }

                        if (xe2.Name == "price")
                        {
                            XmlNodeList xnl2 = xe2.ChildNodes;
                            foreach (XmlNode xn2 in xnl2)
                            {
                                if (xn2.Name == "weight")
                                {
                                    xn2.InnerText = "88";
                                }
                            }
                        }
                    }
                }
            }

            xmlDocument.Save("D:\\book2.xml");
        }

result:

<?xml version="1.0" encoding="GB2312"?>
-<Employees>
-<Node ISB="2-3631-4" Name="李明明">
<title>今天天气不好</title>-<price>
<weight>88</weight>
</price>
</Node>
-<Node2 Name="张三">
<title>心情好</title>
</Node2></Employees>
View Code


4 删除节点:

public void DeleteNode()
        {
            XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.Load("D:\\book1.xml");

            XmlNodeList xnl = xmlDocument.SelectSingleNode("Employees").ChildNodes;

            foreach (XmlNode xn in xnl)
            {
                if (xn.Name == "Node")
                {
                    XmlElement xe = (XmlElement)xn;//将xn的属性转换为XmlElement
                    xe.RemoveAttribute("ID");//移除xe的ID属性
                    XmlNodeList xnl2 = xe.ChildNodes;
                    for (int i = 0; i < xnl2.Count; i++)
                    {
                        XmlElement xe2 = (XmlElement)xnl2.Item(i);
                        if (xe2.Name == "title")
                        {
                            xe.RemoveChild(xe2);//删除节点title
                        }
                    }
                }
            }

            xmlDocument.Save("D:\\book3.xml");
        }

结果:
<?xml version="1.0" encoding="GB2312"?>
-<Employees>
-<Node ISB="2-3631-4" Name="李明">-<price>
<weight>20</weight>
</price>
</Node>-
<Node2 Name="张三">
<title>心情好</title>
</Node2>-
<Node2 Name="张三">
<title>心情好</title>
</Node2>
</Employees>
View Code

 


前面介绍了xml的创建、节点的添加、节点的修改和删除,下面以写的一个保存项目配置文件的小例子。

举例说明:

首先在项目文件中创建一个xml文档:

<?xml version="1.0" encoding="utf-8" ?>
<configurationN>
    <ServerAddress>1143</ServerAddress>
    <ID>192.168</ID>
  </configurationN>

 

在保存配置文件时,最主要使用了两个方法:Load和Save。

Load:初始化xml文档,以便项目文件获取具体的xml节点的值。

public void Load(string path)
        {
            try
            {
                XmlDocument xmlDocument = new XmlDocument();
                xmlDocument.Load(path);

                XmlNodeList xnl = xmlDocument.SelectSingleNode(managerNode).ChildNodes;
                foreach (XmlNode xn in xnl)
                {
                    if (xn.Name == configuration_ServerAddress)
                    {
                        ServerAddress = xn.InnerText;
                    }
                }
            }
            catch(Exception ex)
            { }
        }

 

Save:在项目系统中进行修改配置文件值后,需要对xml进行重新保存

public void Save(string path)
        {
            try
            {
                XmlDocument xmlDocument = new XmlDocument();
                xmlDocument.Load(path);

                XmlNodeList xnl = xmlDocument.SelectSingleNode(managerNode).ChildNodes;
                foreach (XmlNode xn in xnl)
                {
                    if (xn.Name == configuration_ServerAddress)
                    {
                        xn.InnerText = ServerAddress;
                    }
                }

                xmlDocument.Save(path);
            }
            catch (Exception ex)
            { }
        }

 

此处将所有代码都贴出来,方便下次实现。因为项目是WPF文件,而且都是简单控件,所以只贴出后台代码。

class ConfigurationManager:INotifyPropertyChanged 
    {
        public const string managerNode = "configurationN";//根节点
        public const string configuration_ServerAddress = "ServerAddress";//子节点

        private string _ServerAddress;
        public string ServerAddress
        {
            get { return _ServerAddress; }
            set
            {
                _ServerAddress = value;
                NotifyPropertyChanged("ServerAddress");
            }
        }

        public void Load(string path)
        {
            try
            {
                XmlDocument xmlDocument = new XmlDocument();
                xmlDocument.Load(path);

                XmlNodeList xnl = xmlDocument.SelectSingleNode(managerNode).ChildNodes;
                foreach (XmlNode xn in xnl)
                {
                    if (xn.Name == configuration_ServerAddress)
                    {
                        ServerAddress = xn.InnerText;
                    }
                }
            }
            catch(Exception ex)
            { }
        }

        public void Save(string path)
        {
            try
            {
                XmlDocument xmlDocument = new XmlDocument();
                xmlDocument.Load(path);

                XmlNodeList xnl = xmlDocument.SelectSingleNode(managerNode).ChildNodes;
                foreach (XmlNode xn in xnl)
                {
                    if (xn.Name == configuration_ServerAddress)
                    {
                        xn.InnerText = ServerAddress;
                    }
                }

                xmlDocument.Save(path);
            }
            catch (Exception ex)
            { }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public static ConfigurationManager Instance = new ConfigurationManager();
    }




public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Start();
            this.tb1.Text = ConfigurationManager.Instance.ServerAddress.ToString();

        }
        private string path = "CONFIG\\System.xml";

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            ConfigurationManager.Instance.ServerAddress = this.tb1.Text;
            ConfigurationManager.Instance.Save(path);
        }

        private void button2_Click(object sender, RoutedEventArgs e)
        {
            Application.Current.Shutdown();
        }

        private void Start()
        {
            ConfigurationManager.Instance.Load(path);
        }
    }
View Code

 

 

记录在项目中使用xml的实例:

背景:

公司内部系统和第三方系统做对接,http请求得到一个string格式的xml文档,里面包含了大量的字段数据需要解析,如果遍历xml的节点查找节点值也能做,可要是在代码里面写这么多if条件语句,感觉对不起自己写几年代码了。于是有了以下记录,是实际项目的简化版,只介绍思路。

http请求得到的xml:

string strXml =@"<Body>
                    <Result><Code>0</Code><Msg>OK</Msg></Result>
                    <Test><name>data1</name><age>data2</age><score>data3</score></Test></Body>";

为了解析Test的子节点里面的值,编写对应的类,注意,类名一定要对应。

public class Test
    {
        public string name { get; set; }
        public string age { get; set; }
        public string score { get; set; }
    }

解析xml代码如下:

XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.LoadXml(strXml);

            string testrXml = xmlDocument.SelectSingleNode("Body").SelectSingleNode("Test").OuterXml;
            XmlSerializer serializer = new XmlSerializer(typeof(Test));
            using (MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(testrXml)))
            {
                Test mm = (Test)serializer.Deserialize(memoryStream);
            }

补充一点,如果想得到固定格式里面的某个节点的value值,可以使用:

string codeValue  = xmlDocument.SelectSingleNode("Body").SelectSingleNode("Result").SelectSingleNode("Code").InnerText;

 

在前面得到一个Test对象,里面的字段都是需要的值。但是如果需要转换为另外一个系统内已经确定的类,还需要做下面操作:

目标类:

public class DestTest
    {
        public string name { get; set; }
        public string age { get; set; }
        public string totalScore { get; set; }
    }

其中totalScore字段不一致。

处理方法:

using AutoMapper;


public static DestTest GetDto(Test test)
        {
            Mapper.Initialize(m => m.CreateMap<Test, DestTest>().ForMember(dest => dest.totalScore, opt => opt.MapFrom(src => src.score)));
            return Mapper.Map<Test, DestTest>(test);
        }

 

补充:

xml带有命名空间,解析的方式和上文不同,下面记录。

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
    <RunServiceResponse xmlns="http://tempuri.org/">
    <RunServiceResult>0</RunServiceResult>
    <outMsg>
      <Body>
        <Result><Code>7</Code><Msg>OK</Msg></Result>
    </Body>
  </outMsg>
  </RunServiceResponse>
</s:Body>
</s:Envelope>

解析如下:

XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(outMsg2);//outMsg2是xml路径

XmlNamespaceManager xmlnsm = new XmlNamespaceManager(xmlDocument.NameTable);
xmlnsm.AddNamespace("s", "http://schemas.xmlsoap.org/soap/envelope/");
xmlnsm.AddNamespace("m", "http://tempuri.org/");

XmlNode node = xmlDocument.SelectSingleNode("/s:Envelope", xmlnsm);
XmlNode nodeBody = xmlDocument.SelectSingleNode("/s:Envelope/s:Body", xmlnsm);
XmlNode nodeResult = xmlDocument.SelectSingleNode("/s:Envelope/s:Body/m:RunServiceResponse/m:outMsg/m:Body/m:Result", xmlnsm);
string codeValue = xmlDocument.SelectSingleNode("/s:Envelope/s:Body/m:RunServiceResponse/m:outMsg/m:Body/m:Result/m:Code",xmlnsm).InnerText;

找到节点,其它的和普通xml文件类似。

 

 补充2:

写个小实例,描述对AutoMapper的基本应用:

两个实体类:Test,TestDto:

public class Test
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Score { get; set; }
        public int Age { get; set; }
    }

    public class TestDto
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Result { get; set; }
        public int Birth { get; set; }
    }
View Code

初始化实体类:

Test test = new Test{Id = 1,Name = "张三",Score = 99, Age=34};

创建映射:

AutoMapper.Mapper.Initialize(m =>
            {
                m.CreateMap<Test, TestDto>() //创建映射
                    .ForMember(dest => dest.Result, opt => opt.MapFrom(src => src.Score)); //指定映射规则
            });

调用:

TestDto dto = AutoMapper.Mapper.Map<Test, TestDto>(test);

完毕。

附录:

AutoMapper.Mapper.Initialize(m=>
             {
                 m.CreateMap<test, testDTO>()//创建映射
                .ForMember(dest => dest.ArticleID, opt => opt.MapFrom(src => src.Id))//指定映射规则
                .ForMember(dest => dest.Summary, opt => opt.MapFrom(src => src.Content.Substring(0, 10)))//指定映射规则
                .ForMember(dest => dest.PostYear, opt => opt.MapFrom(src => src.PostTime.Year))//指定映射规则
                .ForMember(dest => dest.Remark, opt => opt.Ignore());//指定映射规则 忽视没有的属性
             });

 

 

 

posted @ 2013-11-14 16:10  小项目笔记  阅读(6158)  评论(1编辑  收藏  举报

更多文章请关注公众号:小项目笔记

小项目笔记