2013-04-24 76 views
0

我XML1服務器如下如何同步兩個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.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> 

請給解決這個..在此先感謝

回答

2

M AKE類結構類似

[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; } 
} 

通過使用反串行化的那些個XML轉換爲對象,並調用遞歸方法比較每個節點和合併到第一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; 
    }