现有两个结构一样,但部分节点内容不同的XML文件,需要根据一个XML的ID节点,覆盖另一个XML节点内容.
XML结构如下
<?xml version="1.0" encoding="gb2312"?> <Xml> <Data> <ElementMatchModel id="3b226203-f535-4bdd-bedf-0e42503d613d" name="bxline_bxpoint_0"> <Link>3b226203-f535-4bdd-bedf-0e42503d613d.usx</Link> <BuildingSource></BuildingSource> <SphericalTransform> <Location>118.0850858401120900,24.4822235205172980,-1.5400000000000000</Location> </SphericalTransform> <BBox> <MinBoundary>0.0000000000000000,0.0000000000000000,0.0000000000000000</MinBoundary> <MaxBoundary>0.0000000000000000,0.0000000000000000</MaxBoundary> </BBox> <LonLatRect>0.0000000000000000,0.0000000000000000</LonLatRect> </ElementMatchModel> <ElementMatchModel id="427b5a0e-62e3-4c66-bf5a-5d435c60b96b" name="bxline_bxpoint_1"> <Link>427b5a0e-62e3-4c66-bf5a-5d435c60b96b.usx</Link> <BuildingSource></BuildingSource> <SphericalTransform> <Location>118.0852246123423700,24.4819580362325690,-1.5600000000000001</Location> </SphericalTransform> <BBox> <MinBoundary>0.0000000000000000,0.0000000000000000</LonLatRect> </ElementMatchModel> </Data> </Xml>
代码如下:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO; using System.Xml.Linq; using System.Diagnostics; namespace WindowsFormsApplication1 { public partial class frmXml : Form { public frmXml() { InitializeComponent(); } private void button1_Click(object sender,EventArgs e) { OpenFileDialog fileDialog = new OpenFileDialog(); fileDialog.CheckFileExists = true; fileDialog.CheckPathExists = true; //判断用户是否正确的选择了文件 if (fileDialog.ShowDialog() == DialogResult.OK) { //获取用户选择的文件 FileInfo fileInfo = new FileInfo(fileDialog.FileName); textBox1.Text = fileInfo.FullName; } } private void button2_Click(object sender,EventArgs e) { OpenFileDialog fileDialog = new OpenFileDialog(); fileDialog.CheckFileExists = true; fileDialog.CheckPathExists = true; //判断用户是否正确的选择了文件 if (fileDialog.ShowDialog() == DialogResult.OK) { //获取用户选择的文件 FileInfo fileInfo = new FileInfo(fileDialog.FileName); textBox2.Text = fileInfo.FullName; } } private void button3_Click(object sender,EventArgs e) { if (String.IsNullOrEmpty(textBox1.Text) || String.IsNullOrEmpty(textBox2.Text)) return; XDocument xdocDest = XDocument.Load(textBox1.Text); //需要覆盖的文件 XDocument xdocSelc = XDocument.Load(textBox2.Text); //需要读取的文件 try { //查询并返回“id”,“location”的键值对 var dic = (from ElementMatchModel in xdocSelc.Element("Xml").Element("Data").Elements("ElementMatchModel") select new { id = ElementMatchModel.Attribute("id").Value,location = ElementMatchModel.Element("SphericalTransform").Element("Location").Value }).ToDictionary(o => o.id,o => o.location); foreach (KeyValuePair<string,string> pair in dic) { var selLocCollection = from test in xdocDest.Element("Xml").Element("Data").Elements("ElementMatchModel") where test.Attribute("id").Value == pair.Key select test; //如果找到相同的ID,那么就更新"Location"元素的值 if (selLocCollection.ToArray<XElement>().Length > 0) selLocCollection.Single<XElement>().Element("SphericalTransform").Element("Location").Value = pair.Value; } //覆盖匹配的元素值后,生成一个新文件并保存 xdocDest.Save(System.IO.Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName) + "\\" + "test.xml"); MessageBox.Show("ok"); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } } } }上面是把需要更新的部分返回一个Dictionary,再在循环中查找并更新,原本我想用联合查询更新的,但貌似行不通,非得分几步完成,如有linq高手会用更简洁的代码写出来,不吝赐教!