2009-04-27 23 views
13

Estoy tratando de comparar dos archivos Xml usando el código C#. Quiero ignorar las diferencias de sintaxis Xml (es decir, nombres de prefijos). Para eso estoy usando XML Diff and Patch C# API de Microsoft. Funciona para algunos XML, pero no pude encontrar una manera de configurarlo para que funcione con los dos siguientes de XML:Comparación de Xml en C#

XML A:

<root xmlns:ns="http://myNs"> 
    <ns:child>1</ns:child> 
</root> 

XML B:

<root> 
    <child xmlns="http://myNs">1</child> 
</root> 

Mi las preguntas son:

  1. ¿Tengo razón en que estos dos xml son semánticamente iguales (o isomorfos)?
  2. ¿Se puede configurar la API XML Diff y Patch de Microsoft para que sea compatible?
  3. ¿Hay otras utilidades C# para esto?

Respuesta

2

Tengo an answer by Martin Honnen en XML y .NET Framework MSDN Foro. En resumen, sugiere usar la función de igualdad profunda de XQuery 1.0 y proporciona algunas implementaciones de C#. Parece funcionar.

2

Sé que su foco no está en pruebas unitarias, pero XMLUnit puede comparar dos archivos XML y creo que puede resolver su ejemplo. Tal vez podrías mirar el código y descubrir tu solución.

+0

En realidad, mi atención se centra en las pruebas unitarias. Sin embargo, XMLUnit también parece tener limitaciones similares en .Net. Realmente funcionó para los Xml's anteriores pero una pequeña variación lo rompió. –

1

Puede ser una idea cargar instancias de XmlDocument de cada archivo xml, y comparar el DOM de XML en su lugar? Proporcionar la validación correcta se realiza en cada uno, que debe darle un terreno común para una comparación, y debe permitir el informe de diferencia estándar. Posiblemente incluso la capacidad de actualizar uno del otro con el delta.

+0

Es una opción, pero estoy haciendo algo que creo que es un problema común con una solución común. –

0

Esos documentos no son semánticamente equivalentes. El elemento de nivel superior del primero está en el espacio de nombre http://myNS, mientras que el elemento de nivel superior del segundo está en el espacio de nombre predeterminado.

niño elementos de los dos documentos son equivalentes. Pero los documentos en sí no lo son.

Editar:

Hay un mundo de diferencia entre xmls:ns='http://myNS' y xmlns='http://myNS', que aparezco haber pasado por alto. De todos modos, esos documentos son semánticamente equivalentes y estoy equivocado.

+0

Eso es incorrecto. Los elementos de nivel superior de ambos documentos están en el espacio de nombres predeterminado.El elemento de nivel superior del primer documento solo puede estar en el espacio de nombres http: // myNs si se declara como o

10

Los documentos son isomorfos, como se puede ver en el programa a continuación. Creo que si usa XmlDiffOptions.IgnoreNamespaces y XmlDiffOptions.IgnorePrefixes para configurar Microsoft.XmlDiffPatch.XmlDiff, obtendrá el resultado que desea.

using System.Linq; 
using System.Xml.Linq; 
namespace SO_794331 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var docA = XDocument.Parse(
       @"<root xmlns:ns=""http://myNs""><ns:child>1</ns:child></root>"); 
      var docB = XDocument.Parse(
       @"<root><child xmlns=""http://myNs"">1</child></root>"); 

      var rootNameA = docA.Root.Name; 
      var rootNameB = docB.Root.Name; 
      var equalRootNames = rootNameB.Equals(rootNameA); 

      var descendantsA = docA.Root.Descendants(); 
      var descendantsB = docB.Root.Descendants(); 
      for (int i = 0; i < descendantsA.Count(); i++) 
      { 
       var descendantA = descendantsA.ElementAt(i); 
       var descendantB = descendantsB.ElementAt(i); 
       var equalChildNames = descendantA.Name.Equals(descendantB.Name); 

       var valueA = descendantA.Value; 
       var valueB = descendantB.Value; 
       var equalValues = valueA.Equals(valueB); 
      } 
     } 
    } 
} 
+1

IgnorarNamespaces no es bueno para mí: considero que los documentos con diferentes espacios de nombres son semánticamente diferentes. –

+0

Entiendo, pero parece que XML Patch & Diff tiene en cuenta los espacios de nombres al comparar, incluso cuando se usa IgnoreNamespaces. Probé esto con dos documentos y . Diff & Patch piensa que son diferentes. Desafortunadamente, ahora no tengo el código, así que no puedo confirmarlo al 100%. –

+0

A y B en mi comentario anterior estaban destinados a ser dos urls pero se convirtieron en enlaces ... –