在实际项目中遇到一些关于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 = "";
xeSub2.AppendChild(xeSub3); root.AppendChild(xe1);
xmlDoc.Save("D:\\book.xml");//保存的路径
}

结果:

<?xml version="1.0" encoding="GB2312"?>
-<Employees>-
  <Node ISB="2-3631-4" Name="李明">
    <title>学习VS</title>-
    <price>
      <weight></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></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 = "";
}
}
}
}
}
} xmlDocument.Save("D:\\book2.xml");
} result: <?xml version="1.0" encoding="GB2312"?>
-<Employees>
-<Node ISB="2-3631-4" Name="李明明">
<title>今天天气不好</title>-<price>
<weight></weight>
</price>
</Node>
-<Node2 Name="张三">
<title>心情好</title>
</Node2></Employees>

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 = ; 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></weight>
</price>
</Node>-
<Node2 Name="张三">
<title>心情好</title>
</Node2>-
<Node2 Name="张三">
<title>心情好</title>
</Node2>
</Employees>

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

举例说明:

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

<?xml version="1.0" encoding="utf-8" ?>
<configurationN>
<ServerAddress></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);
}
}

记录在项目中使用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></RunServiceResult>
<outMsg>
<Body>
<Result><Code></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; }
}

初始化实体类:

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

创建映射:

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(, )))//指定映射规则
.ForMember(dest => dest.PostYear, opt => opt.MapFrom(src => src.PostTime.Year))//指定映射规则
.ForMember(dest => dest.Remark, opt => opt.Ignore());//指定映射规则 忽视没有的属性
});

xml基本操作的更多相关文章

  1. boost::xml——基本操作以及中文乱码解决方案

    下面是本人使用boost库的xml部分的基础操作,并且解决对于大家使用boost库读写中文xml内容出现的乱码问题. 1.实现boost库xml基本操作2.解决boost对xml中中文乱码问题3.实现 ...

  2. boost::xml——基本操作以及中文乱码解决方案 (续)

    本博文主要想说明以下两点: 1.对于上一篇的<boost::xml——基本操作以及中文乱码解决方案>解释,这篇博文基本解决了正确输入输出中英文问题,但是好像还没有解决修改中文出现乱码的问题 ...

  3. C# 对XML基本操作总结

    C# 对XML基本操作包括读取节点的数据,添加节点.读取节点属性,修改节点属性等.具体如下: XML文件:文件在MyDocument文件夹下 <?xml version="1.0&qu ...

  4. xml基本操作和保存配置文件应用实例

    引言:在实际项目中遇到一些关于xml操作的问题,被逼到无路可退的时候终于决定好好研究xml一番.本文首先介绍了xml的基本操作,后面写了一个经常用到的xml保存配置文件的实例. xml常用方法: 定义 ...

  5. linq to xml 基本操作

    使用XDocument类来进行简单的xml操作,用于软件参数的设置保存. using System; using System.Collections.Generic; using System.Li ...

  6. LINQ to XML基本操作

    Linq to XML同样是对原C#访问XML文件的方法的封装,简化了用xpath进行xml的查询以及增加,修改,删除xml元素的操作. LINQ to XML 三个最重要类:XElement.XAt ...

  7. linq to xml学习

    http://www.cnblogs.com/greatverve/archive/2010/07/09/linq-to-xml-add-delete-update-query.html 记录一下,别 ...

  8. JAVA中通过Jaxp操作XML文件基础

    Java中有多种方式操作XML文件,目前讲一讲以SUN公司提供的DocumentBuilderFactory工厂类对象操作XML. 使用XML基本操作就是需要CRUD(增删改查),那么首先通过一个查询 ...

  9. 【原创】日志文件清理工具V1.0

    最近公司的系统服务器经常出现磁盘空间不足的情况,登陆服务器发现原来是公司的HR系统日志造成的(插个话题:我们公司的HR系统都实施两年多了还没上线,且不说软件功能如何,服务太TMD差劲了,更可气的是软件 ...

随机推荐

  1. IE11的API变化

    IE11已经登录Win8.1,它的API有了很大变更 一.User-agent字符串的更改 IE10的是 Mozilla/5.0 (compatible; MSIE 10.0; Windows NT ...

  2. CentOS6.5上golang环境配置

    CentOS6.5上golang环境配置 一.下载和解压go环境包 >>cd /usr/local/src/ >>wget -c http://golangtc.com/sta ...

  3. 虚拟机Linux----Ubuntu1204----设置固定Ip

    1.介绍 环境:ubuntu版本是12.04,虚拟机是Oracle Vm VirtualBox 2.说明 需求:现在已经安装了一个ubuntu系统,网络配置是默认选择桥接,可以上网,物理机可以连接虚拟 ...

  4. HDU 3374 String Problem (KMP+最大最小表示)

    KMP,在有循环节的前提下: 循环节 t = len-next[len], 个数num = len/(len-next[len]);个人理解,如果有循环节,循环节长度必定小于等于len/2, 换句话说 ...

  5. NOIP2008普及组传球游戏(动态规划)——yhx

    题目描述 上体育课的时候,小蛮的老师经常带着同学们一起做游戏.这次,老师带着同学们一起做传球游戏. 游戏规则是这样的:n个同学站成一个圆圈,其中的一个同学手里拿着一个球,当老师吹哨子时开始传球,每个同 ...

  6. 利用HttpListener创建简单的HTTP服务

    using System; using System.Collections.Generic; using System.IO; using System.IO.Compression; using ...

  7. C#委托与C语言函数指针及函数指针数组

    C#委托与C语言函数指针及函数指针数组 在使用C#时总会为委托而感到疑惑,但现在总新温习了一遍C语言后,才真正理解的委托. 其实委托就类似于C/C++里的函数指针,在函数传参时传递的是函数指针,在调用 ...

  8. 看程序写结果(program)

    看程序写结果(program) Time Limit:1000ms Memory Limit:64MB 题目描述 LYK 最近在准备 NOIP2017 的初赛,它最不擅长的就是看程序写结果了,因此它拼 ...

  9. NGUI Sprite Type(Simple、Sliced、Tiled、Filed、Advanced)

    官方文档:http://www.tasharen.com/forum/index.php?topic=6704.0 Sprite Type 下面是UISprite的Type截图,每一种Type都有不同 ...

  10. Unity 物理引擎动力学关节

    Unity物理引擎中的各个动力学关节 Hinge Joint (铰链关节) Fixed Joint (固定关节) Spring Joint (弹簧关节) Character Joint(角色关节) C ...