针对Xml文件对比,有两种情况,一种是单纯的行对行比较,一种是结点比较
针对单纯的行对行比较,比较常用的工具有 svnmerge, winmerge, ExamDiff等,前两个是基于UI的,即结果只会打印在界面中,无法导出,所以如果要继承在程序中是件比较困难的事情,但是ExamDiff可以将结果以文件的形式导出来,所以嵌入到程序中就不是难事
如果要进行结点比较,目前我只尝试了使用LinQ写代码实现,当然这种方式做出来的程序只能针对特定的XML,如果XML中结点改变程序就得跟着改变
目前,LinQ的程序事例很多
粘出几个自己的例子,以备用
XML格式如下
<document case="lower" version="0.1">
<global>
<tmspolicy PCNNumber="888" AreaType="DTC,GVA" DeploymentType="VAS/LOG" ThrottleMessages="200000" ThrottleBytes="124999875">
<MsFilterNorth PEListInclusive="true">
<PEFilter>
<Item PE="-1" />
<Item PE="2" />
<Item PE="4" />
<Item PE="5" />
<Item PE="6" />
<Item PE="7" />
<Item PE="8" />
<Item PE="9" />
<Item PE="10" />
<Item PE="11" />
<Item PE="12" />
</PEFilter>
</MsFilterNorth>
<TrafficManager
DefaultQueueIndex="1"
EQMMemoryRisingThreshold="90"
EQMMemoryFallingThreshold="75"
EQMOverflowFallingThreshold="95"
NewsQueueIndex="0"
NumberOfQueues="3"
OutputThrottleMessages="200000"
OutputThrottleBytes="124999875"
UDTQueueIndex="0">
<Queue-1 AggregationDelayThreshold="-1"
DailyBreachThresholdTime="-1"
DailyBreachDuration="840"
ExceptionalDuration="300"
ExceptionalDelayResetTime="3600"
ExceptionalDelayLatencyThreshold="-1"
GuaranteedQuota="80"
ITMAware="true"
GuaranteedMemoryQuota="50"
PerRICThrottleInterval="-1"
PRTOverloadDelayThreshold="-1"
QueuePriority="2"
SpareQuota="45"
StrictPRTOverload="false">
<ITMUnawarePEs>
</ITMUnawarePEs>
<PEList>
<Item PE="-1" />
<Item PE="2" />
<Item PE="4" />
<Item PE="5" />
<Item PE="6" />
<Item PE="7" />
<Item PE="8" />
<Item PE="9" />
<Item PE="10" />
<Item PE="11" />
<Item PE="12" />
<Item PE="13" />
<Item PE="14" />
<Item PE="15" />
<Item PE="17" />
</PEList>
</Queue-1>
<Queue1 AggregationDelayThreshold="500"
DailyBreachThresholdTime="-1"
DailyBreachDuration="840"
ExceptionalDuration="300"
ExceptionalDelayResetTime="3600"
ExceptionalDelayLatencyThreshold="-1"
GuaranteedQuota="10"
ITMAware="true"
GuaranteedMemoryQuota="15"
PerRICThrottleInterval="-1"
PRTOverloadDelayThreshold="-1"
QueuePriority="1"
SpareQuota="0"
StrictPRTOverload="false">
<ITMUnawarePEs>
</ITMUnawarePEs>
<PEList>
<Item PE="0" />
<Item PE="1" />
<Item PE="3" />
</PEList>
</Queue1>
<Queue2 AggregationDelayThreshold="500"
DailyBreachThresholdTime="-1"
DailyBreachDuration="840"
ExceptionalDuration="300"
ExceptionalDelayResetTime="3600"
ExceptionalDelayLatencyThreshold="-1"
GuaranteedQuota="10"
ITMAware="true"
GuaranteedMemoryQuota="10"
PerRICThrottleInterval="-1"
PRTOverloadDelayThreshold="-1"
QueuePriority="0"
SpareQuota="55"
StrictPRTOverload="false">
<ITMUnawarePEs>
</ITMUnawarePEs>
<PEList>
<Item PE="1952" />
<Item PE="2382" />
<Item PE="3774" />
<Item PE="5571" />
<Item PE="5589" />
<Item PE="6562" />
<Item PE="6786" />
<Item PE="7999" />
</PEList>
</Queue2>
</TrafficManager>
</tmspolicy>
</global>
</document>
特定代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace TMSXmlCompare
{
class Program
{
static void Main(string[] args)
{
XDocument docA = XDocument.Load("D:\\VSWorkSpace\\TMSXmlCompare\\A.xml");
XDocument docB = XDocument.Load("D:\\VSWorkSpace\\TMSXmlCompare\\B.xml");
#region tmspolicy
var resultTmspolicy1 = from tmspolicy1 in docA.Descendants("tmspolicy")
from tmspolicy2 in docB.Descendants("tmspolicy")
select new
{
book1 = new
{
PCNNumber = tmspolicy1.Attribute("PCNNumber").Value,
AreaType = tmspolicy1.Attribute("AreaType").Value,
DeploymentType = tmspolicy1.Attribute("DeploymentType").Value,
ThrottleMessages = tmspolicy1.Attribute("ThrottleMessages").Value,
ThrottleBytes = tmspolicy1.Attribute("ThrottleBytes").Value
},
book2 = new
{
PCNNumber = tmspolicy2.Attribute("PCNNumber").Value,
AreaType = tmspolicy2.Attribute("AreaType").Value,
DeploymentType = tmspolicy2.Attribute("DeploymentType").Value,
ThrottleMessages = tmspolicy2.Attribute("ThrottleMessages").Value,
ThrottleBytes = tmspolicy2.Attribute("ThrottleBytes").Value
}
};
var resultTmspolicy2 = from i in resultTmspolicy1
where (!(i.book1.PCNNumber == i.book2.PCNNumber
&& i.book1.AreaType == i.book2.AreaType
&& i.book1.DeploymentType == i.book2.DeploymentType
&& i.book1.ThrottleMessages == i.book2.ThrottleMessages
&& i.book1.ThrottleBytes== i.book2.ThrottleBytes
))
select i;
if (resultTmspolicy2.Count() > 0)
{
Console.Write("<tmspolicy ");
foreach (XAttribute element in docB.Descendants("tmspolicy").Attributes())
{
Console.Write(element.Name + "=\"" + element.Value + "\" ");
}
Console.Write(">\n");
}
#endregion
Console.WriteLine("---------------");
#region MsFilterNorth PEFilter
//A is the new file, B is the old
//deletePart means the PE in B but not in A
//addPart means the PE in A but not in B
var deletePart = (from aPrj in docA.Descendants("tmspolicy").Descendants("MsFilterNorth").Descendants("PEFilter").Descendants("Item")
select aPrj.Attribute("PE").Value
).Except(
from bPrj in docB.Descendants("tmspolicy").Descendants("MsFilterNorth").Descendants("PEFilter").Descendants("Item")
select bPrj.Attribute("PE").Value);
var addPart = (from bPrj in docB.Descendants("tmspolicy").Descendants("MsFilterNorth").Descendants("PEFilter").Descendants("Item")
select bPrj.Attribute("PE").Value
).Except(
from aPrj in docA.Descendants("tmspolicy").Descendants("MsFilterNorth").Descendants("PEFilter").Descendants("Item")
select aPrj.Attribute("PE").Value);
if (deletePart.Count() > 0 || addPart.Count() > 0)
{
Console.Write("<tmspolicy-<MsFilterNorth-<PEFilter>\n");
if (deletePart.Count() > 0)
{
Console.ForegroundColor = ConsoleColor.Yellow;
foreach (string vv in deletePart)
{
Console.Write("<Item PE=\"" + vv + "\"/ >\n");
}
}
if (addPart.Count() > 0)
{
Console.ForegroundColor = ConsoleColor.Green;
foreach (string vv in addPart)
{
Console.Write("<Item PE=\"" + vv + "\"/ >\n");
}
}
}
#endregion
Console.WriteLine("---------------");
#region TrafficManager
var resultTrafficManager1 = from TrafficManager1 in docA.Descendants("TrafficManager")
from TrafficManager2 in docB.Descendants("TrafficManager")
select new
{
book1 = new
{
DefaultQueueIndex = TrafficManager1.Attribute("DefaultQueueIndex").Value,
EQMMemoryRisingThreshold = TrafficManager1.Attribute("EQMMemoryRisingThreshold").Value,
EQMMemoryFallingThreshold = TrafficManager1.Attribute("EQMMemoryFallingThreshold").Value,
EQMOverflowFallingThreshold = TrafficManager1.Attribute("EQMOverflowFallingThreshold").Value,
NewsQueueIndex = TrafficManager1.Attribute("NewsQueueIndex").Value,
NumberOfQueues = TrafficManager1.Attribute("NumberOfQueues").Value,
OutputThrottleMessages = TrafficManager1.Attribute("OutputThrottleMessages").Value,
OutputThrottleBytes = TrafficManager1.Attribute("OutputThrottleBytes").Value,
UDTQueueIndex = TrafficManager1.Attribute("UDTQueueIndex").Value
},
book2 = new
{
DefaultQueueIndex = TrafficManager2.Attribute("DefaultQueueIndex").Value,
EQMMemoryRisingThreshold = TrafficManager2.Attribute("EQMMemoryRisingThreshold").Value,
EQMMemoryFallingThreshold = TrafficManager2.Attribute("EQMMemoryFallingThreshold").Value,
EQMOverflowFallingThreshold = TrafficManager2.Attribute("EQMOverflowFallingThreshold").Value,
NewsQueueIndex = TrafficManager2.Attribute("NewsQueueIndex").Value,
NumberOfQueues = TrafficManager2.Attribute("NumberOfQueues").Value,
OutputThrottleMessages = TrafficManager2.Attribute("OutputThrottleMessages").Value,
OutputThrottleBytes = TrafficManager2.Attribute("OutputThrottleBytes").Value,
UDTQueueIndex = TrafficManager2.Attribute("UDTQueueIndex").Value
}
};
var resultTrafficManager2 = from i in resultTrafficManager1
where (!(i.book1.DefaultQueueIndex == i.book2.DefaultQueueIndex
&& i.book1.EQMMemoryRisingThreshold == i.book2.EQMMemoryRisingThreshold
&& i.book1.EQMMemoryFallingThreshold == i.book2.EQMMemoryFallingThreshold
&& i.book1.EQMOverflowFallingThreshold == i.book2.EQMOverflowFallingThreshold
&& i.book1.NewsQueueIndex == i.book2.NewsQueueIndex
&& i.book1.NumberOfQueues == i.book2.NumberOfQueues
&& i.book1.OutputThrottleMessages == i.book2.OutputThrottleMessages
&& i.book1.OutputThrottleBytes == i.book2.OutputThrottleBytes
&& i.book1.UDTQueueIndex == i.book2.UDTQueueIndex
))
select i;
if (resultTrafficManager2.Count()> 0)
{
Console.ForegroundColor = ConsoleColor.DarkYellow;
Console.Write("<TrafficManager ");
foreach (XAttribute att in docB.Descendants("TrafficManager").Attributes())
{
Console.Write(att.Name.ToString() + "=\"" + att.Value + "\" ");
}
Console.Write(">\n");
}
#endregion
Console.WriteLine("---------------");
#region compare the queue number
var deletQueue = (from aPrj in docA.Descendants("TrafficManager").Elements()
select aPrj.Name).Except(
from bPrj in docB.Descendants("TrafficManager").Elements()
select bPrj.Name
);
if (deletQueue.Count() > 0)
{
Console.ForegroundColor = ConsoleColor.Yellow;
foreach (XName vv in deletQueue)
{
XElement element = docA.Descendants(vv).First();
Console.Write(element);
Console.Write("\n");
}
Console.Write("\n");
}
var addQueue = (from bPrj in docB.Descendants("TrafficManager").Elements()
select bPrj.Name).Except(
from aPrj in docA.Descendants("TrafficManager").Elements()
select aPrj.Name
);
if (addQueue.Count() > 0)
{
Console.ForegroundColor = ConsoleColor.Green;
foreach (XName vv in addQueue)
{
XElement element = docB.Descendants(vv).First();
Console.Write(element);
Console.Write("\n");
}
Console.Write("\n");
}
Console.Write("\n");
var equalQueue = from aPrj in docA.Descendants("TrafficManager").Elements()
join bPrj in docB.Descendants("TrafficManager").Elements()
on aPrj.Name equals bPrj.Name
select
aPrj;
foreach (XElement dd in equalQueue)
{
IEnumerable<XElement> ffd= docB.Descendants(dd.Name).Descendants("PEList").Elements();
IEnumerable<XElement> ffr= docA.Descendants(dd.Name).Descendants("PEList").Elements();
var addEqualQueue = (from bPrj in docB.Descendants(dd.Name).Descendants("PEList").Elements()
select bPrj.Attribute("PE").Value
).Except(
from aPrj in docA.Descendants(dd.Name).Descendants("PEList").Elements()
select aPrj.Attribute("PE").Value
);
var deleteEqualQueue = (from aPrj in docA.Descendants(dd.Name).Descendants("PEList").Elements()
select aPrj.Attribute("PE").Value
).Except(
from bPrj in docB.Descendants(dd.Name).Descendants("PEList").Elements()
select bPrj.Attribute("PE").Value
);
if (addEqualQueue.Count() > 0 || deleteEqualQueue.Count() > 0)
{
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("<"+dd.Name+">");
if (addEqualQueue.Count() > 0)
{
Console.ForegroundColor = ConsoleColor.Green;
foreach (string vv in addEqualQueue)
{
Console.Write("<Item PE=\"" + vv + "\" />\n");
}
Console.Write("\n");
}
if (deleteEqualQueue.Count() > 0)
{
Console.ForegroundColor = ConsoleColor.Yellow;
foreach (string vv in deleteEqualQueue)
{
Console.Write("<Item PE=\"" + vv + "\" />\n");
}
Console.Write("\n");
}
}
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("</" + dd.Name + ">");
}
#endregion
var queueDiff = docA.Descendants("TrafficManager").Elements().Except(docB.Descendants("TrafficManager").Elements());
}
}
}
打印出结果大致如下: