XmlDiff и сценарий использования исправления в https://docs.microsoft.com/en-us/previous-versions/dotnet/articles/aa302294 (v=msdn.10)

#xmldiff

#xmldiff

Вопрос:

Я должен иметь возможность сравнивать два XML-файла, которые взяты из одного и того же xsd, получать различия, включая добавление, удаление и обновление. Мне также нужно получить значение перед обновлением, если обновление произошло.

XmlDiff и патч выглядели многообещающе, и я решил написать несколько кодов, чтобы попробовать себя на примере из статьи, но у меня есть разные исправленные результаты в зависимости от того, как выглядит второй 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. Эксперимент 1

Два xml-файла имеют одинаковое количество «model»-ов в одинаковом порядке, но во втором 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. Experiment 2

The second xml has Outback’s two tags updated and one new model Impreza. This is what is described in the article.

[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>
  

[Patched-up results]

  1. Outback Muffler has its prefix ns1, but WindShieldWipers’s one is ns2 while both are updated from the second xml. Does anyone understand why Outback Muffler prefix is ns1?
  2. All of elements of Impreza should have its prefix ns2 as this model does not appear in the original xml, but has WindShieldWipers ns1. Why is this?
     <?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. Эксперимент 3

Во втором xml удалена устаревшая модель, добавлена новая модель 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