title: Compare two XML files and save differences to a results file
body: <p>I have two XML files that I need to compare for differences, the XML is very simple:</p>
  
  <p>File 1:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;Feeds zone="my zone"&gt;
    &lt;Feed name="attribDump.json"&gt;ac1f07edc491a3d237cdfb1a17fc4551&lt;/Feed&gt;
    &lt;Feed name="focus_GroupsKV.txt"&gt;0f9e0a14a4ffce6ff5065b6e088c1f84&lt;/Feed&gt;
    &lt;Feed name="NAM_FORMATTED.csv"&gt;9e875496cdb072b5e54318d51295fdba&lt;/Feed&gt;
    &lt;Feed name="BNP\activityTitles.txt"&gt;2d27c0f19b71b4b411bcb00011d3f8b0&lt;/Feed&gt;
  &lt;/Feeds&gt;
  </code></pre>
  
  <p>and File 2:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;FeedsRequest version="1"&gt;
  &lt;Feeds zone="my zone"&gt;
    &lt;Feed name="attribDump.json"&gt;ac1f07edc491a3d237cdfb1a17fc4551&lt;/Feed&gt;
    &lt;Feed name="focus_GroupsKV.txt"&gt;0f9e0a14a4ffce6ff5065b6e088c1f84&lt;/Feed&gt;
    &lt;Feed name="BNP\activityTitles.txt"&gt;e54c5b851ee3ff3f43b10d24f2316431&lt;/Feed&gt;
  &lt;/Feeds&gt;
  &lt;/FeedsRequest&gt;
  </code></pre>
  
  <p>File 1 is an inventory list of files on our file share and File 2 is used by a disconnected device that will need to be refreshed from File 1.  The checks I need to make are 1) make sure all of the feeds in File 1 are in File 2 and 2) make sure any feeds that are found have the same hashCode(the long character string).  Once the checks have been completed, I need to create a response file that has a list of all of the feeds and then an attribute on each one that designates ok (file was found and matched), missing (file wasn't found), or updated (file was found but it was an older version).  </p>
  
  <p>So basically the result file would look as such:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;FeedsResponse version="1"&gt;
  &lt;Feeds zone="my zone"&gt;
    &lt;Feed name="attribDump.json" status="ok"&gt;ac1f07edc491a3d237cdfb1a17fc4551&lt;/Feed&gt;
    &lt;Feed name="focus_GroupsKV.txt" status="ok"&gt;0f9e0a14a4ffce6ff5065b6e088c1f84&lt;/Feed&gt;
    &lt;Feed name="NAM_FORMATTED.csv" status="missing"&gt;afd2c620053ed4f85ab02b4cc5f7a2b2&lt;/Feed&gt;
    &lt;Feed name="BNP\activityTitles.txt" status="updated"&gt;90805b851ee3ff3f43b10d24f2316431&lt;/Feed&gt;
  </code></pre>
  
  <p>What I'm doing currently is looping through all of the files in File 1, then checking them against File 2 for differences.  Where I'm stuck, been a while since I've worked with XML, is how to build out the response document.  </p>
  
  <pre><code>            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 &lt; 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 &lt; feedRequestXml.Count &amp;&amp; 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();
          }
  </code></pre>
  
  <p>Right now I'm trying to instantiate the response doc before the loop and then just add the elements as they are found but I'm having a hard time finding a concise way to do it.  Any help is appreciated.</p>