2013-08-19 105 views
0

我有我需要比較的差異兩個XML文件的差異,XML是非常簡單的:比較兩個XML文件,並保存到結果文件

文件1:

<?xml version="1.0" encoding="utf-8"?> 
<Feeds zone="my zone"> 
    <Feed name="attribDump.json">ac1f07edc491a3d237cdfb1a17fc4551</Feed> 
    <Feed name="focus_GroupsKV.txt">0f9e0a14a4ffce6ff5065b6e088c1f84</Feed> 
    <Feed name="NAM_FORMATTED.csv">9e875496cdb072b5e54318d51295fdba</Feed> 
    <Feed name="BNP\activityTitles.txt">2d27c0f19b71b4b411bcb00011d3f8b0</Feed> 
</Feeds> 

和文件2 :

<?xml version="1.0" encoding="utf-8"?> 
<FeedsRequest version="1"> 
<Feeds zone="my zone"> 
    <Feed name="attribDump.json">ac1f07edc491a3d237cdfb1a17fc4551</Feed> 
    <Feed name="focus_GroupsKV.txt">0f9e0a14a4ffce6ff5065b6e088c1f84</Feed> 
    <Feed name="BNP\activityTitles.txt">e54c5b851ee3ff3f43b10d24f2316431</Feed> 
</Feeds> 
</FeedsRequest> 

文件1是對我們的文件共享和文件2個文件是使用斷開連接的設備,將需要的清單列表從文件1.刷新我需要有1支票)確保所有的 文件1中的提要位於文件2和2中)確保找到的所有提要具有相同的hashCode(長字符字符串)。一旦檢查完成後,我需要創建一個響應文件,其中包含所有提要的列表,然後指定每個提要的屬性(文件已找到並匹配),缺少(找不到文件),或更新(文件被發現,但它是一箇舊版本)。

所以基本上結果文件將如下這樣:

<?xml version="1.0" encoding="utf-8"?> 
<FeedsResponse version="1"> 
<Feeds zone="my zone"> 
    <Feed name="attribDump.json" status="ok">ac1f07edc491a3d237cdfb1a17fc4551</Feed> 
    <Feed name="focus_GroupsKV.txt" status="ok">0f9e0a14a4ffce6ff5065b6e088c1f84</Feed> 
    <Feed name="NAM_FORMATTED.csv" status="missing">afd2c620053ed4f85ab02b4cc5f7a2b2</Feed> 
    <Feed name="BNP\activityTitles.txt" status="updated">90805b851ee3ff3f43b10d24f2316431</Feed> 

我在做什麼目前通過所有文件的循環在文件1,然後檢查他們對文件2的差異。在我被困住的地方,自從我使用過XML以來,已經有一段時間了,是如何構建響應文檔的。

  FileInfo feedList = new FileInfo(_feedList); 
     FileInfo feedRequest = new FileInfo(_feedRequest); 

     // Load the documents 
     XmlDocument feedListXmlDoc = new XmlDocument(); 
     feedListXmlDoc.Load(_feedList); 

     // Load the documents 
     XmlDocument feedRequestXmlDoc = new XmlDocument(); 
     feedRequestXmlDoc.Load(_feedRequest); 

     //create response doc 
     XmlDocument feedResponseXmlDoc = new XmlDocument(); 

     // Define a single node 
     XmlNode feedListNode; 
     XmlNode feedRequestNode; 

     // Get the root Xml element 
     XmlElement feedListRoot = feedListXmlDoc.DocumentElement; 
     XmlElement feedRequestRoot = feedRequestXmlDoc.DocumentElement; 

     // Get a list of all player names 
     XmlNodeList feedListXml = feedListRoot.GetElementsByTagName("Feed"); 
     XmlNodeList feedRequestXml = feedRequestRoot.GetElementsByTagName("Feed"); 

     // Create an XmlWriterSettings object with the correct options. 
     XmlWriter writer = null; 
     XmlWriterSettings settings = new XmlWriterSettings(); 
     settings.Indent = true; 
     settings.IndentChars = (" "); 
     settings.OmitXmlDeclaration = false; 

     // Create the XmlWriter object and write some content. 
     writer = XmlWriter.Create(_resultPath, settings); 
     writer.WriteStartElement("FeedsDiff"); 

     // The compare algorithm 
     bool feedMatch = false; 

     int j = 0; 

     try 
     { 
      // loop through list of current feeds 
      for (int i = 0; i < feedListXml.Count; i++) 
      { 
       feedListNode = feedListXml.Item(i); 

       string feedListName = feedListNode.Attributes["name"].Value.ToString(); 
       string feedListHash = feedListXml.Item(i).InnerText.ToString(); 

       //check feed request list for a match 
       while (j < feedRequestXml.Count && feedMatch == false) 
       { 
        feedRequestNode = feedRequestXml.Item(j); 
        string feedRequestName = feedRequestNode.Attributes["name"].Value.ToString(); 

        //checks to see if feed names match 
        if (feedListName == feedRequestName) 
        { 
         feedMatch = true; 
         string feedRequestHash = feedRequestXml.Item(j).InnerText.ToString(); 

         //since we found the node, we can remove it from the request list 
         XmlNode node = feedRequestNode.ParentNode; 
         node.RemoveChild(feedRequestNode); 

         //checks to see if hash codes match 
         if (feedListHash == feedRequestHash) 
         { 
          //if name and code match, move to the next one 
          feedMatch = true; 

          //add 'status="ok"' attribute to the node 
          //feedResponseXmlDoc.ImportNode(feedRequestNode,false); 

          Debug.WriteLine(feedListName + " name and hash match"); 

          j = 0; 
         } 
         else 
         { 

          feedMatch = true; 

          //feed has been updated since last device sync 
          //need to add status='update' attribute and append file to response 
          Debug.WriteLine(feedListName + " name matched but hash did not"); 
         } 
        } 
        else 
        { 
         //names didn't match 
         //add status="missing" to the node 
         j++; 
        } 
       } 
       feedMatch = false; 
      } 
      // end Xml document 
      writer.WriteEndElement(); 
      writer.Flush(); 
     } 
     finally 
     { 
      if (writer != null) 
       writer.Close(); 
     } 

現在,我試圖實例循環之前的響應文檔,然後只需添加的元素,因爲他們被發現,但我有一個很難找到一個簡潔的方式來做到這一點。任何幫助表示讚賞。

+1

你能證明你的代碼的,是有關您已發佈的問題..? – MethodMan

+0

按要求添加。我知道它在循環內有點薄,這就是我卡住的地方。 – TrevorGoodchild

回答

0

我想通了:

public void CompareXml(string _feedList, string _feedRequest, string _resultPath) 
    { 
     FileInfo feedList = new FileInfo(_feedList); 
     FileInfo feedRequest = new FileInfo(_feedRequest); 

     // Load the documents 
     XmlDocument feedListXmlDoc = new XmlDocument(); 
     feedListXmlDoc.Load(_feedList); 

     // Load the documents 
     XmlDocument feedRequestXmlDoc = new XmlDocument(); 
     feedRequestXmlDoc.Load(_feedRequest); 

     // Define a single node 
     XmlNode feedListNode; 
     XmlNode feedRequestNode; 

     // Get the root Xml element 
     XmlElement feedListRoot = feedListXmlDoc.DocumentElement; 
     XmlElement feedRequestRoot = feedRequestXmlDoc.DocumentElement; 

     // Get a list of feeds for the stored list and the request 
     XmlNodeList feedListXml = feedListRoot.GetElementsByTagName("Feed"); 
     XmlNodeList feedRequestXml = feedRequestRoot.GetElementsByTagName("Feed"); 

     bool feedLocated = false; 
     int j = 0; 

     try 
     { 
      // loop through list of current feeds 
      for (int i = 0; i < feedListXml.Count; i++) 
      { 
       feedListNode = feedListXml.Item(i); 
       //create status attribute 
       XmlAttribute attr = feedListXmlDoc.CreateAttribute("status"); 

       string feedListName = feedListNode.Attributes["name"].Value.ToString(); 
       string feedListHash = feedListXml.Item(i).InnerText.ToString(); 

       //check feed request list for a match 
       while (j < feedRequestXml.Count && feedLocated == false) 
       { 
        feedRequestNode = feedRequestXml.Item(j); 
        string feedRequestName = feedRequestNode.Attributes["name"].Value.ToString(); 

        //checks to see if feed names match 
        if (feedRequestName == feedListName) 
        { 
         string feedRequestHash = feedRequestXml.Item(j).InnerText.ToString(); 

         //checks to see if hashCodes match 
         if (feedListHash == feedRequestHash) 
         { 
          //if name and code match, set status to ok 
          attr.Value = "ok"; 

          Debug.WriteLine(feedListName + " name and hash match. Status: 'ok'"); 
         } 
         else 
         { 
          //if hashCodes don't match, set status attribute to updated 
          attr.Value = "updated"; 

          Debug.WriteLine(feedListName + " name matched but hash did not. Status: 'updated'"); 
         } 
         feedListNode.Attributes.Append(attr); 
         feedLocated = true; 
        } 
        else 
        { 
         //names didn't match, checking to see if we're at the end of the request list 
         if (j + 1 == feedRequestXml.Count) 
         { 
          //file name wasn't found in the request list, set status attribute to missing 
          attr.Value = "missing"; 
          feedListNode.Attributes.Append(attr); 
          feedLocated = true; 
          j = 0; 

          Debug.WriteLine("Reached the end of the file request list without a match. Status: 'missing'"); 
         } 
         //file name wasn't located on this pass, move to next record 
         j++; 
        } 
       } 
       feedLocated = false; 
      } 
     } 
     finally 
     { 
      Debug.WriteLine("Result file has been written out at " + _resultPath); 
     } 

     feedListXmlDoc.Save(_resultPath); 
    } 
0

看看我的開源項目CodeBlocks在CodePlex上的differ,它是爲這樣的情況而設計的。它也可在作爲的NuGet「differ