【问题标题】:How to synchronize two xml files?如何同步两个xml文件?
【发布时间】:2013-04-24 09:47:43
【问题描述】:

我在服务器中有如下 XML1

  <?xml version="1.0" encoding="utf-8"?>
<Node id="0" Value="Root">
<Node id="1" Value="L1">
<Node id="1.1" Value="N11">
  <Node id="1.1.2" Value="N112" />
 </Node>
</Node>
<Node id="2" Value="L2">
<Node id="2.1" Value="N21" />
 </Node>
</Node>

我在本地还有另一个 XML2,如下所示

<?xml version="1.0" encoding="utf-8"?>
<Node id="0" Value="Root">
 <Node id="1" Value="L1">
<Node id="1.1" Value="N11"></Node>
<Node id="1.2" Value="N12"></Node>
 </Node>
<Node id="2.1" Value="N21"></Node>
</Node>

现在我想同步这两个 xml 并输出如下

<?xml version="1.0" encoding="utf-8"?>
<Node id="0" Value="Root">
 <Node id="1" Value="L1">
<Node id="1.1" Value="N11" />
<Node id="1.2" Value="N12" />
  </Node>
  <Node id="2.1" Value="N21" />
</Node>

请给出解决方案..提前谢谢

【问题讨论】:

    标签: xml merge sync


    【解决方案1】:

    制作类结构

     [XmlTypeAttribute(AnonymousType = true)]
    public class Node
    {
        [XmlAttribute(AttributeName = "id")]
        public string Id { get; set; }
    
        [XmlAttribute(AttributeName = "Value")]
        public string Name { get; set; }
    
        [XmlAttribute(AttributeName = "Status")]
        public string Status { get; set; }
    
        [XmlElement("Node")]
        public List<Node> Nodes { get; set; }
    }
    

    通过使用反序列化将这些xmls转换为一个对象并调用递归方法来比较每个节点并合并到第一个xml中。

    private void sync_Click(object sender, EventArgs e)
        {
            strLogg = string.Empty;
            Node oSource = FillData(textBox1.Text + ".xml");
            Node oDesignation = FillData(textBox2.Text + ".xml");
            UpdateNodes(oSource, oDesignation);
            WriteXML(oSource,"XML1.xml");
            string strHeader = "Changes at " + DateTime.Now + System.Environment.NewLine;
            System.IO.File.AppendAllText(exportPath + "xmlLogger.txt",  strHeader + strLogg + Environment.NewLine);
            //System.Diagnostics.Process.Start(exportPath + "\\xmlLogger.txt"); // show log file
    
        }
    
    
     private static Node FillData(string xmlName)
        {
            string path = exportPath + xmlName;
            FileStream fs = new FileStream(path, FileMode.Open);
            XmlReader reader = new XmlTextReader(fs);
            XmlRootAttribute xRoot = new XmlRootAttribute("Node");
            xRoot.IsNullable = true;
            var serializer = new XmlSerializer(typeof(Node), xRoot);
            var result = (Node)serializer.Deserialize(reader);
            reader.Close();
    
            return result;
        }
    
    
    private void UpdateNodes(Node n1, Node n2)
        {
            // Update Value
            if (n1.Name != n2.Name)
            {
                LogChanges(n1.Name + " Changed as " + n2.Name);
            }
    
            n1.Name = n2.Name;
            if (n1.Nodes != null || n2.Nodes != null)
            {
    
                if ((n1.Nodes != null && n1.Nodes.Count > 0) && (n2.Nodes != null && n2.Nodes.Count > 0))
                {
                    // add new nodes to XML1
                    var newNodes = n2.Nodes.Where(ns => (!(n1.Nodes.Select(nn => nn.Id).ToList()).Contains(ns.Id) && ns.Status != "del")).ToList();
                    newNodes.ForEach(n => LogChanges("Added " + n.Name));
                    n1.Nodes.AddRange(newNodes);
    
                    // delete nodes from XML1
                    var delNodes = n2.Nodes.Where(ns => ((n1.Nodes.Select(nn => nn.Id).ToList()).Contains(ns.Id) && ns.Status == "del")).ToList();
                    if (delNodes.Count > 0)
                    {
                        delNodes.ForEach(n => LogChanges("Deleted " + n.Name));
                    }
                    n1.Nodes.RemoveAll(ns => n2.Nodes.Count(nn => nn.Id == ns.Id && nn.Status == "del") > 0);
    
    
                    if (n2.Nodes.Count > 0 && n2.Nodes.Count > 0)
                    {
                        n1.Nodes.ToList().ForEach(n =>
                        {
                            if (n2.Nodes.Count(ns2 => ns2.Id == n.Id) > 0)
                            {
                                UpdateNodes(n, n2.Nodes.Where(ns2 => ns2.Id == n.Id).FirstOrDefault());
                            }
                        }
                            );
                    }
                }
                else if ((n1.Nodes != null && n1.Nodes.Count > 0) && (n2.Nodes == null || n2.Nodes.Count == 0))
                {
                    n2.Nodes = new List<Node>();
                    n2.Nodes.AddRange(n1.Nodes);
                }
                else if ((n1.Nodes == null || n1.Nodes.Count == 0) && (n2.Nodes != null && n2.Nodes.Count > 0 && n2.Nodes.Count(ns => ns.Status !="del") > 0))
                {
                    n1.Nodes = new List<Node>();
                    n1.Nodes.AddRange(n2.Nodes);
                    n2.Nodes.ForEach(n => LogChanges("Added  " + n.Name));
                }
            }
        }
    
    
        private void LogChanges(string sName)
        {
            strLogg +=  sName +  System.Environment.NewLine;
        }
    

    【讨论】:

      猜你喜欢
      • 2020-02-11
      • 2018-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-07
      • 2012-09-09
      相关资源
      最近更新 更多