假如读者访问过MSDN的"XML Notepad 2006设计"页面(http://www.microsoft.com/china/msdn/library/data/xml/xmlnotepad.mspx?mfr=true),可能想去下载XML Notepad 2006的源代码,看看如何比较XML。但是,很遗憾,下载页面只有XML Notepad 2007的程序可以下载,并没有源码。再看看作者的修改记录(Change History),其中有个地方提到"Move source code to CodePlex",OK,再去CodePlex网站上去搜搜看。我再次很抱歉的告诉您,那里也没有源代码,只有若干关于XML Notepad的问题。
别丧气,本文要讲的,就是把XML notepad 2007中比较XML文件并显式差异的功能分离出来,并应用到自己的程序中。想想看,"自己的"程序能够比较XML文件,多么令人兴奋的一件事情!
先别急,这个应用是有限制的: 目前只能在.net 2.0开发的程序中引入这个功能。至于语言,我是用C#尝试的,从理论上讲VB也可以,其他语言没有试验过。我是今年1月初的时候做的尝试,现在XML notepad 2007好像已经是2.3版了,如果原来的方法不能奏效,也别怪我。
另外需要说明的,如果是非商业用途的程序,版权问题不大; 如果作为商业用途,请自己解决版权问题。
言归正传,现在讲如何做,这个应该是大家最关心的。
先去http://www.microsoft.com/china/MSDN/library/data/xml/XMLDiffPatchGUITool.mspx?mfr=true下载"XML差异与修补工具",安装之后在VS .NET 2005中打开这个工程,VS会自动弹出一个窗口询问"是否进行版本转换",选择"是"。然后编译、运行即可。
研究一下,程序依赖两个dll文件对XML进行比较并生成HTML代码,但是这两个dll很古老:xmldiffpatch.dll是2002年的,XmlDiffPatch.View.dll是2004年的。而且,多比较一些XML文件,就会发现比较结果的显示有点小问题。
那就再想办法"升级"xmldiffpatch.dll和XmlDiffPatch.View.dll。
下载并安装XML Notepad 2007,打开XML Notepad 2007的安装目录,xmldiffpatch.dll和XmlDiffPatch.View.dll映入眼帘,这两个文件看着很眼熟啊。没错,就是这两个文件。把它们复制到刚才的xmlDiffView工程目录下,覆盖原来的文件,然后在工程中重新添加引用(reference)。佛祖保佑,编译通过。运行,比较XML文件--表示差异的背景颜色怎么都没了?
看来还得再做点工作,想办法把颜色加上,不然比较XML的功能就损失大半了。再次研究,看看记录xml文件差异的临时html文件(貌似要用调试模式运行xmlDiffView,在调用比较XML函数的代码处设断点,单步运行,能看到临时文件)。如果读者具有一定的html知识,就会发现,<body>…</body>中使用了大量的css标签。这个好办,找到下面的代码
sw1.Write(
"
<html><body><table width='100%'>
"
);
// Write Legend.
sw1.Write( " <tr><td colspan='2' align='center'><b>Legend:</b> <font style='background-color: yellow' " +
" color='black'>added</font> <font style='background-color: red' " +
" color='black'>removed</font> <font style='background-color: " +
" lightgreen' color='black'>changed</font> " +
" <font style='background-color: red' color='blue'>moved from</font> " +
" <font style='background-color: yellow' color='blue'>moved to " +
" </font> <font style='background-color: white' color='#AAAAAA'> " +
" ignored</font></td></tr> " );
// Write Legend.
sw1.Write( " <tr><td colspan='2' align='center'><b>Legend:</b> <font style='background-color: yellow' " +
" color='black'>added</font> <font style='background-color: red' " +
" color='black'>removed</font> <font style='background-color: " +
" lightgreen' color='black'>changed</font> " +
" <font style='background-color: red' color='blue'>moved from</font> " +
" <font style='background-color: yellow' color='blue'>moved to " +
" </font> <font style='background-color: white' color='#AAAAAA'> " +
" ignored</font></td></tr> " );
替换成下面的代码
string
htmlHeader
=
"
<html><head>
"
+ " <style type=\ " text / css\ " ><!-- " // css
+ " .add {color: black;background-color: yellow;} " // add
+ " .remove {color: black;background-color: red;} " // remove
+ " .change {color: black;background-color: lightgreen;} " // change
+ " .movefrom {color: blue;background-color: red;} " // movefrom
+ " .moveto {color: blue;background-color: yellow;} " // ignore
+ " .ignore {color=\ " #AAAAAA\ " ;background-color: white;} " // moveto
+ " --></style> "
+ " <title>comparision</title></head><body><table width='100%'> " // Write Title
// Write Legend.
+ " <tr><td colspan='2' align='center'><b>Legend:</b> "
+ " <font style='background-color: yellow' color='black'>added</font> "
+ " <font style='background-color: red' color='black'>removed</font> "
+ " <font style='background-color: lightgreen' color='black'>changed</font> "
+ " <font style='background-color: red' color='blue'>moved from</font> "
+ " <font style='background-color: yellow' color='blue'>moved to</font> "
+ " <font style='background-color: white' color='#AAAAAA'>ignored</font> "
+ " </td></tr> " ;
sw1.Write(htmlHeader);
+ " <style type=\ " text / css\ " ><!-- " // css
+ " .add {color: black;background-color: yellow;} " // add
+ " .remove {color: black;background-color: red;} " // remove
+ " .change {color: black;background-color: lightgreen;} " // change
+ " .movefrom {color: blue;background-color: red;} " // movefrom
+ " .moveto {color: blue;background-color: yellow;} " // ignore
+ " .ignore {color=\ " #AAAAAA\ " ;background-color: white;} " // moveto
+ " --></style> "
+ " <title>comparision</title></head><body><table width='100%'> " // Write Title
// Write Legend.
+ " <tr><td colspan='2' align='center'><b>Legend:</b> "
+ " <font style='background-color: yellow' color='black'>added</font> "
+ " <font style='background-color: red' color='black'>removed</font> "
+ " <font style='background-color: lightgreen' color='black'>changed</font> "
+ " <font style='background-color: red' color='blue'>moved from</font> "
+ " <font style='background-color: yellow' color='blue'>moved to</font> "
+ " <font style='background-color: white' color='#AAAAAA'>ignored</font> "
+ " </td></tr> " ;
sw1.Write(htmlHeader);
再次编译,运行,看看比较xml文件的结果,是不是大功告成了?
最后,就是在自己的程序中添加上面提到的两个dll,把相关的代码复制过来,根据自己需要再改改就好了。这样,自己的.net 2.0程序也就有比较XML的功能了。
当然,还有一些细节问题,比如比较xml格式string,或者把结果输出为文件,这里就不一一叙述了,读者自己动手解决吧。