1

我必须能够比较来自同一个 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>

[修补结果]

  1. Outback Muffler 有其前缀 ns1,但 WindShieldWipers 的前缀是 ns2,而两者都是从第二个 xml 更新的。有谁明白为什么 Outback Muffler 前缀是 ns1?
  2. 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>

[修补结果]

  1. Outback的更新标签应该有前缀ns2,但只有一个有它??
  2. 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

4

0 回答 0