我必须能够比较来自同一个 xsd 的两个 xml,获得包括添加、删除和更新在内的差异。如果发生更新,我还需要在更新之前获取一个值。
XmlDiff 和 Patch 看起来很有希望,我决定根据文章中的示例编写一些代码来尝试自己,但是根据第二个 xml 的外观,我有各种不同的修补结果。
这是我的尖刺代码。
public void TestDiffGram()
{
using (var sw = new StringWriter(CultureInfo.InvariantCulture))
{
var settings = new XmlWriterSettings();
settings.Indent = true;
settings.OmitXmlDeclaration = true;
using (var xw = XmlWriter.Create(sw, settings))
{
var ignore = XmlDiffOptions.IgnoreWhitespace |
XmlDiffOptions.IgnorePrefixes |
XmlDiffOptions.IgnoreNamespaces;
var xmldiff = new XmlDiff(ignore);
xmldiff.Algorithm = XmlDiffAlgorithm.Fast;
xmldiff.Compare("c://Temp//xml1.xml", "c://Temp//xml2.xml", false, xw);
xw.Close();
}
File.WriteAllText("c://Temp//diffgram.xml", sw.ToString());
XmlDocument sourceDoc = new XmlDocument(new NameTable());
sourceDoc.LoadXml(File.ReadAllText("c://Temp//xml1.xml"));
XmlTextReader diffgramReader = new XmlTextReader("c://Temp//diffgram.xml");
new XmlPatch().Patch(sourceDoc, diffgramReader);
XmlTextWriter output = new XmlTextWriter("c://Temp//test.xml", Encoding.Unicode);
sourceDoc.Save(output);
output.Close();
}
}
xml1.xml 和 xml2.xml 是本文中两个 xml 的变体。
1. 实验一
两个 xml 以相同的顺序具有相同数量的“模型”,但在第二个 xml 中更新了 Outback 的两个标签。
[xml1.xml]
<PartPriceInfo xmlns:ns1="http://www.Subaru.com">
<ns1:Subaru model="Outback">
<ns1:Muffler> 500 </ns1:Muffler>
<ns1:Bumper> 150 </ns1:Bumper>
<ns1:Floormat> 75 </ns1:Floormat>
<ns1:WindShieldWipers> 20 </ns1:WindShieldWipers>
</ns1:Subaru>
<ns1:Subaru model="Legacy">
<ns1:Muffler> 400 </ns1:Muffler>
<ns1:Bumper> 100 </ns1:Bumper>
<ns1:Floormat> 50 </ns1:Floormat>
<ns1:WindShieldWipers> 20 </ns1:WindShieldWipers>
</ns1:Subaru>
</PartPriceInfo>
[xml2.xml]
<PartPriceInfo xmlns:ns2="http://www.Subaru.com">
<ns2:Subaru model="Outback">
<ns2:Muffler> 600 </ns2:Muffler>
<ns2:Bumper> 150 </ns2:Bumper>
<ns2:Floormat> 75 </ns2:Floormat>
<ns2:WindShieldWipers> 25 </ns2:WindShieldWipers>
</ns2:Subaru>
<ns2:Subaru model="Legacy">
<ns2:Muffler> 400 </ns2:Muffler>
<ns2:Bumper> 100 </ns2:Bumper>
<ns2:Floormat> 50 </ns2:Floormat>
<ns2:WindShieldWipers> 20 </ns2:WindShieldWipers>
</ns2:Subaru>
</PartPriceInfo>
[修补结果]
模型 Outback 具有更新的这两个元素,但我希望前缀是 ns2,但它是 ns1,如下所示。为什么是这样?
<?xml version="1.0" encoding="UTF-8"?>
<PartPriceInfo xmlns:ns1="http://www.Subaru.com">
<ns1:Subaru model="Outback">
<ns1:Muffler>600</ns1:Muffler>
<ns1:Bumper>150</ns1:Bumper>
<ns1:Floormat>75</ns1:Floormat>
<ns1:WindShieldWipers>25</ns1:WindShieldWipers>
</ns1:Subaru>
<ns1:Subaru model="Legacy">
<ns1:Muffler>400</ns1:Muffler>
<ns1:Bumper>100</ns1:Bumper>
<ns1:Floormat>50</ns1:Floormat>
<ns1:WindShieldWipers>20</ns1:WindShieldWipers>
</ns1:Subaru>
</PartPriceInfo>
2. 实验二
第二个 xml 更新了 Outback 的两个标签和一个新模型 Impreza。这就是文章中描述的内容。
[xml1.xml]
<PartPriceInfo xmlns:ns1="http://www.Subaru.com">
<ns1:Subaru model="Outback">
<ns1:Muffler> 500 </ns1:Muffler>
<ns1:Bumper> 150 </ns1:Bumper>
<ns1:Floormat> 75 </ns1:Floormat>
<ns1:WindShieldWipers> 20 </ns1:WindShieldWipers>
</ns1:Subaru>
<ns1:Subaru model="Legacy">
<ns1:Muffler> 400 </ns1:Muffler>
<ns1:Bumper> 100 </ns1:Bumper>
<ns1:Floormat> 50 </ns1:Floormat>
<ns1:WindShieldWipers> 20 </ns1:WindShieldWipers>
</ns1:Subaru>
</PartPriceInfo>
[xml2.xml]
<PartPriceInfo xmlns:ns2="http://www.Subaru.com">
<ns2:Subaru model="Outback">
<ns2:Muffler> 600 </ns2:Muffler>
<ns2:Bumper> 150 </ns2:Bumper>
<ns2:Floormat> 75 </ns2:Floormat>
<ns2:WindShieldWipers> 25 </ns2:WindShieldWipers>
</ns2:Subaru>
<ns2:Subaru model="Legacy">
<ns2:Muffler> 400 </ns2:Muffler>
<ns2:Bumper> 100 </ns2:Bumper>
<ns2:Floormat> 50 </ns2:Floormat>
<ns2:WindShieldWipers> 20 </ns2:WindShieldWipers>
</ns2:Subaru>
<ns2:Subaru model="Impreza">
<ns2:Muffler> 450 </ns2:Muffler>
<ns2:Bumper> 120 </ns2:Bumper>
<ns2:Floormat> 65 </ns2:Floormat>
<ns2:WindShieldWipers> 20 </ns2:WindShieldWipers>
</ns2:Subaru>
</PartPriceInfo>
[修补结果]
- Outback Muffler 有其前缀 ns1,但 WindShieldWipers 的前缀是 ns2,而两者都是从第二个 xml 更新的。有谁明白为什么 Outback Muffler 前缀是 ns1?
- Impreza 的所有元素都应具有前缀 ns2,因为该模型未出现在原始 xml 中,但具有 WindShieldWipers ns1。为什么是这样?
<?xml version="1.0" encoding="UTF-8"?>
<PartPriceInfo xmlns:ns1="http://www.Subaru.com">
<ns1:Subaru model="Outback">
<ns1:Muffler>600</ns1:Muffler>
<ns1:Bumper>150</ns1:Bumper>
<ns1:Floormat>75</ns1:Floormat>
<ns2:WindShieldWipers xmlns:ns2="http://www.Subaru.com">25</ns2:WindShieldWipers>
</ns1:Subaru>
<ns1:Subaru model="Legacy">
<ns1:Muffler>400</ns1:Muffler>
<ns1:Bumper>100</ns1:Bumper>
<ns1:Floormat>50</ns1:Floormat>
<ns1:WindShieldWipers>20</ns1:WindShieldWipers>
</ns1:Subaru>
<ns2:Subaru xmlns:ns2="http://www.Subaru.com" model="Impreza">
<ns2:Muffler>450</ns2:Muffler>
<ns2:Bumper>120</ns2:Bumper>
<ns2:Floormat>65</ns2:Floormat>
<ns1:WindShieldWipers>20</ns1:WindShieldWipers>
</ns2:Subaru>
</PartPriceInfo>
3. 实验三
第二个 xml 删除了模型 Legacy,添加了新模型 Impreza,并更新了模型 Outback 的两个标签。
[xml1.xml]
<PartPriceInfo xmlns:ns1="http://www.Subaru.com">
<ns1:Subaru model="Outback">
<ns1:Muffler> 500 </ns1:Muffler>
<ns1:Bumper> 150 </ns1:Bumper>
<ns1:Floormat> 75 </ns1:Floormat>
<ns1:WindShieldWipers> 20 </ns1:WindShieldWipers>
</ns1:Subaru>
<ns1:Subaru model="Legacy">
<ns1:Muffler> 400 </ns1:Muffler>
<ns1:Bumper> 100 </ns1:Bumper>
<ns1:Floormat> 50 </ns1:Floormat>
<ns1:WindShieldWipers> 20 </ns1:WindShieldWipers>
</ns1:Subaru>
</PartPriceInfo>
[xml2.xml]
<PartPriceInfo xmlns:ns2="http://www.Subaru.com">
<ns2:Subaru model="Outback">
<ns2:Muffler> 600 </ns2:Muffler>
<ns2:Bumper> 150 </ns2:Bumper>
<ns2:Floormat> 75 </ns2:Floormat>
<ns2:WindShieldWipers> 25 </ns2:WindShieldWipers>
</ns2:Subaru>
<ns2:Subaru model="Impreza">
<ns2:Muffler> 450 </ns2:Muffler>
<ns2:Bumper> 120 </ns2:Bumper>
<ns2:Floormat> 65 </ns2:Floormat>
<ns2:WindShieldWipers> 20 </ns2:WindShieldWipers>
</ns2:Subaru>
</PartPriceInfo>
[修补结果]
- Outback的更新标签应该有前缀ns2,但只有一个有它??
- Impreza的所有标签都应该是ns2,但都是ns1??
<?xml version="1.0" encoding="UTF-8"?>
<PartPriceInfo xmlns:ns1="http://www.Subaru.com">
<ns1:Subaru model="Outback">
<ns1:Muffler>600</ns1:Muffler>
<ns1:Bumper>150</ns1:Bumper>
<ns1:Floormat>75</ns1:Floormat>
<ns2:WindShieldWipers xmlns:ns2="http://www.Subaru.com">25</ns2:WindShieldWipers>
</ns1:Subaru>
<ns1:Subaru model="Impreza">
<ns1:Muffler>450</ns1:Muffler>
<ns1:Bumper>120</ns1:Bumper>
<ns1:Floormat>65</ns1:Floormat>
<ns1:WindShieldWipers>20</ns1:WindShieldWipers>
</ns1:Subaru>
</PartPriceInfo>
我的期望是,如果修补后的结果具有来自第二个文件的值,那么它将与前缀 ns2 相关联,但有时确实如此。有时它不会。难道我的期望不对吗?我很乐意根据期望得到纠正。
Xoxo