2

The following test fails. r1 seems to be missing angle brackets, does anyone know way? I imagine its some sort of encoding error?

var nav1 = XElement.Load(stream).CreateNavigator(); 
var nav2 = new XPathDocument(stream).CreateNavigator();

using (var r1 = new StringWriter())
using (var r2 = new StringWriter())
{
  xslt.Transform(nav1, null, r1);
  xslt.Transform(nav2, null, r2);

  r1.ToString().Should().Equal(r2.ToString());
}

The problem here is not as far as I can tell semantically equivalent but lexically different xml, but that the resulting xml in the r1 case is missing it's xml tags. Interestingly, using var nav3 = XElement.Load(stream).CreateReader(); works fine.

George Mauer
  • 117,483
  • 131
  • 382
  • 612

2 Answers2

2

Comparing two XML documents using their string representation is not a good idea. While the two documents may be equivalent, they still could have many lexical differences, among them:

  • Different prefixes bound to the same namespace.
  • Use/not use CDATA sections
  • represent/not-represent as strings inherited namespace nodes
  • use quotes vs apostrophes
  • use vs not-use character entities.
  • ..., etc.

I would recommend a better way of doing this -- there are many xmldiff tools. You could also build your own XML comparison tool (as I have done for myself) based on my answer to this question.

UPDATE:

After clarifications from the OP:

"The problem here is not as far as I can tell semantically equivalent but lexically different xml, but that the resulting xml in the r1 case is missing it's xml tags"

I investigated and came up with the following conclusion:

The XslCompiledTransform.Transform(IXPathNavigable, XsltArgumentList, Stream) works with either XmlDocument or XPathDocument as the first argument, as is described in the MSDN documentation.

Parameters     
   inputType: System.Xml.XPath.IXPathNavigable An object    
              implementing the IXPathNavigable interface. In the Microsoft .NET Framework, this
              can  be either an XmlNode (typically an XmlDocument), or 
              an XPathDocument containing the data to be transformed.

As the Navigator created from an XElement obviously doesn't fit in this category, the reported problem is observed.

Solution:

Change:

var nav1 = XElement.Load(stream).CreateNavigator();

to:

var nav1 = XDocument.Load(stream).CreateNavigator();

      

Here is complete code that has been verified to work as expected:

using System.IO;
using System.Xml.Linq;
using System.Xml.XPath;
using System.Xml.Xsl;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace TestLINQ_Xml
{
    class Program
    {
        static void Main(string[] args)
        {
            test();
        }

        static void test()
        {
            XslCompiledTransform xslt = new XslCompiledTransform();
            xslt.Load(@"C:\temp\delete\XSLT.xsl");

            FileStream stream = 
              new FileStream(@"C:\temp\delete\sourceXML.xml", FileMode.Open);

            var xdoc = XDocument.Load(stream);
            var nav1 = xdoc.CreateNavigator();

            stream.Seek(0L, SeekOrigin.Begin);
            var nav2 = new XPathDocument(stream).CreateNavigator(); 

            using (var r1 = new StringWriter()) using (var r2 = new StringWriter()) 
            {   xslt.Transform(nav2, null, r1); 
                xslt.Transform(nav1, null, r2); 

                string  res1 = r1.ToString();
                string  res2 = r2.ToString();

                Assert.AreEqual(res1, res2);
            } 
        }
    }
}
Community
  • 1
  • 1
Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431
  • Point taken, but the question is not really about xmldiff, but about why the output would be different in one of the cases - it actually does not contain any xml tags at all once I do ToString(). – George Mauer Sep 12 '11 at 19:13
  • @George Mauer: I have updated my answer with what I believe is the reason for the problem. I also provide a simple solution. – Dimitre Novatchev Sep 13 '11 at 03:53
0

I reproduced your result. My input XML contains 2 namespaces, in output XMLs namespaces are defined in different order. You can check your output byte by byte and find differences.

Kirill Polishchuk
  • 54,804
  • 11
  • 122
  • 125