2015-12-14 51 views
3

我一直在做各種各樣的方法來比較XML文件的目錄,以便每個「實際構建」XML文件都有一個匹配的「模板構建」XML文件。這些模板將成爲未來構建的實際配置文件,因此我需要回到當前正在運行的配置文件並檢查數據的差異。這些差異將作爲未來版本的客戶端可更改配置。複雜的XML區別

我已經看過XML Diff和Patch(包括GUI和VisStu形式)並嘗試獲得差異,但它會返回異常左側和右側,並且永遠不會獲得創建的diffGram。看起來XD & P正在尋找不再存在或已經被破壞的庫元素。

現在,我是全新的XML和LINQ,但我知道這是我的答案所在。我一直在想創建路徑字符串的每一行,使得下面的XML文件:

<configuration> 
<title>#ClientOfficialName# Interactive Map</title> 
<subtitle>Powered By Yada</subtitle> 
<logo>assets/images/mainpageglobe.png</logo> 
<style alpha="0.9"> 
    <colors>0xffffff,0x777777,0x555555,0x333333,0xffffff</colors> 
    <font name="Verdana"/> 
    <titlefont name="Verdana"/> 
    <subtitlefont name="Verdana"/> 
</style> 

會創建這樣的字符串:

configuration/title/"#ClientOfficialName# Interactive Map" 
configuration/subtitle/"Powered By Yada" 
configuration/logo/"assets/iamges/mainpageglobe.png" 
configuration/style/alpha/"0.9" 
configuration/style/colors/"0xffffff,0x777777,0x555555,0x333333,0xffffff" 

等等這樣。

以這種方式,我可以從實際和模板文件中獲取每一行,並根據「如果它們具有相同的節點路徑,然後比較文本進行比較」。如果所有確切的兄弟文本不匹配,字符串放入differenceOutput.txt「。

到目前爲止,這是我提出的最好的概念。如果任何人都可以幫助我實現這個目標(通過這個或任何其他方法),我將不勝感激。

我現在有工作沒有問題的目錄系統,我只是不知道在哪裏從XML文件中的字符串容器的人口開始:

static void Main(string[] args) 
{ 
    //Set Up File Paths 
    var actualBuildPath = @"C:\actual"; 
    var templateBuildPath = @"C:\template"; 

    //Output File Setups 
    var missingFileList = new List<string>(); 
    var differenceList = new List<string>(); 

    //Iterate through Template Directory checking to see if the Current Build Directory 
    //has everything and finding differences if they exist 
    foreach (var filePath in Directory.GetFiles(templateBuildPath, "*.xml", SearchOption.AllDirectories)) 
    { 
     //Announce Current File 
     Console.WriteLine("File: {0} ", filePath); 

     //Make Sure file Exists in current build 
     if (File.Exists(filePath.Replace(templateBuildPath, actualBuildPath))) 
     { 
      //Fill in String Containers as prep for comparison 
      var templateBuildFormattedXmlLines = PopulateStringContainerFromXML(filePath); 
      var actualBuildFormattedXmlLines = PopulateStringContainerFromXML(filePath.Replace(templateBuildPath, actualBuildPath)); 

      //COMPARISON SECTION------------------------------------------------------- 
      xmlFileCompare(templateBuildFormattedXmlLines, actualBuildFormattedXmlLines); 
     } 
     //Put missing file into missing file output file 
     else 
      missingFileList.Add("Missing: " + filePath.Replace(templateBuildPath, actualBuildPath)); 
    } 

    //Create Output Folder and Output Files 
    if (!Directory.Exists(actualBuildPath + @"\Outputs")) 
     Directory.CreateDirectory(actualBuildPath + @"\Outputs"); 
    File.WriteAllLines(actualBuildPath + @"\Outputs\MissingFiles.txt", missingFileList); 
    File.WriteAllLines(actualBuildPath + @"\Outputs\differenceList.txt", differenceList); 

    //Wait to close console until user interacts 
    Console.ReadLine(); 
} 
+0

您可以使用DataSet方法ReadXML的()讀取XML,然後比較數據表。 Web上有很多示例用於比較兩個數據表。 – jdweng

+0

謝謝jdweng!我現在就開始研究數據表。 –

回答

1

假設所有的配置文件是相同的(語法上)我會推薦將它們讀入一個對象中,並比較這些對象,這樣就有可能進行更細緻的比較,例如可以忽略字幕。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Xml.Linq; 

namespace XMLTest 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
//You can use the XDocument.Load() Method to load a xml from a file path rather than a string 
      string xml = "<configuration><title>#ClientOfficialName# Interactive Map</title><subtitle>Powered By Yada</subtitle><logo>assets/images/mainpageglobe.png</logo><style alpha=\"0.9\"> <colors>0xffffff,0x777777,0x555555,0x333333,0xffffff</colors> <font name=\"Verdana\"/> <titlefont name=\"Verdana\"/> <subtitlefont name=\"Verdana\"/></style></configuration>"; 
      XDocument d = XDocument.Parse(xml); 
      Configuration c = new Configuration(); 
      c.Title = d.Descendants().Where(x => x.Name == "title").FirstOrDefault().Value; 
      c.SubTitle = d.Descendants().Where(x => x.Name == "subtitle").FirstOrDefault().Value; 
      c.Logo = d.Descendants().Where(x => x.Name == "logo").FirstOrDefault().Value; 

      Configuration.Style s = new Configuration.Style(); 
      s.Alpha = (from attr in d.Descendants().Attributes() select attr).Where(x => x.Name == "alpha").FirstOrDefault().Value; 
      string tmp = d.Descendants().Where(x => x.Name == "colors").FirstOrDefault().Value; 
      foreach (string str in tmp.Split(',')) 
      { 
       s.Colors.Add(Convert.ToInt32(str, 16)); 
      } 
      s.FontName = (from attr in d.Descendants().Where(x=>x.Name =="font").Attributes() select attr).Where(x => x.Name == "name").FirstOrDefault().Value; 
      s.TitleFontName = (from attr in d.Descendants().Where(x => x.Name == "titlefont").Attributes() select attr).Where(x => x.Name == "name").FirstOrDefault().Value; 
      s.SubtitleFontName = (from attr in d.Descendants().Where(x => x.Name == "subtitlefont").Attributes() select attr).Where(x => x.Name == "name").FirstOrDefault().Value; 

      c.MyStyle = s; 

      Console.WriteLine(c.ToString()); 
      Console.ReadKey(); 
     } 
    } 
    public class Configuration : IComparable 
    { 

     public string Title; 
     public string SubTitle; 
     public string Logo; 
     public Style MyStyle; 

     public override string ToString() 
     { 
      return string.Format("Configuration : Title: {0}, Subtitle {1}, Logo {2}, Style: {3}",Title,SubTitle,Logo,MyStyle.ToString()); 
     } 
     public class Style 
     { 
      public string Alpha; 
      public List<int> Colors = new List<int>(); 
      public string FontName; 
      public string TitleFontName; 
      public string SubtitleFontName; 

      public override string ToString() 
      { 
       string s = "Alpha :" +Alpha; 
       s+= ", Colors: "; 
       foreach(int i in Colors){ 
        s += string.Format("{0:x},",i); 
       } 
       s += " FontName :" + FontName; 
       s += " TitleFontName :" + TitleFontName; 
       s += " SubTitleFontName :" + SubtitleFontName; 
       return s; 
      } 
     } 

     public int CompareTo(object obj) 
     { 
      if ((obj as Configuration) == null) 
      { 
       throw new ArgumentException("Not instance of configuration"); 
      } 
      //Very simple comparison, ranks by the title in the comparison object, here you could compare all the other values e.g Subtitle , logo and such to test if two instances are Equal 
      return String.Compare(this.Title, ((Configuration)obj).Title, true); 
     } 
    } 
} 

爲了實現比較的更完整的概述,請參閱:https://msdn.microsoft.com/en-us/library/system.icomparable.compareto%28v=vs.110%29.aspx