• 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());//指定映射规则 忽视没有的属性
                 });
  • 相关阅读:
    链表问题----反转部分单向链表
    HTTP请求详解
    链表问题----删除链表的中间节点和a/b处的节点
    链表问题----删除倒数第K个节点
    栈和队列----最大值减去最小值小于等于num的子数组的数量
    栈和队列----求最大子矩阵的大小
    TCP/IP、Http、Socket的区别
    栈和队列----生成窗口的最大值数组
    linux根文件系统制作,busybox启动流程分析
    linux 内核启动流程分析,移植
  • 原文地址:https://www.cnblogs.com/ysyn/p/3423529.html
Copyright © 2020-2023  润新知