Разница между XElement.CreateNavigator () и XPathDocument (). CreateNavigator () - PullRequest
2 голосов
/ 12 сентября 2011

Следующий тест не пройден. В r1, похоже, отсутствуют угловые скобки, кто-нибудь знает способ? Я представляю свою ошибку кодирования?

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());
}

Проблема здесь не в том, насколько я могу сказать, семантически эквивалентный, а в лексически различном xml, но в том, что в получающемся xml в случае r1 отсутствуют теги xml. Интересно, что использование var nav3 = XElement.Load(stream).CreateReader(); отлично работает.

Ответы [ 2 ]

2 голосов
/ 12 сентября 2011

Сравнение двух XML-документов с использованием их строкового представления не очень хорошая идея .Хотя эти два документа могут быть эквивалентными, они все же могут иметь много лексических различий, среди них:

  • Различные префиксы, привязанные к одному пространству имен.
  • Использовать / не использовать разделы CDATA
  • представляют / не представляют как строки, унаследованные узлы пространства имен
  • используют кавычки против апострофов
  • используют против неиспользуемых символьных сущностей.
  • ... и т. Д.

Я бы порекомендовал лучший способ сделать это - существует множество xmldiff инструментов .Вы также можете создать свой собственный инструмент сравнения XML (как я сделал для себя), основываясь на моем ответе на на этот вопрос .

ОБНОВЛЕНИЕ :

После разъяснений из ОП:

"Проблема здесь не в том, насколько я могу сказать, семантически эквивалентный, но лексически отличающийся xml, но в том, что полученный xml в случае r1отсутствует xml-теги "

Я исследовал и пришел к следующему выводу :

XslCompiledTransform.Transform (IXPathNavigable, XsltArgumentList, Stream) работает слибо XmlDocument, либо XPathDocument в качестве первого аргумента, как описано в документации MSDN .

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.

Поскольку Навигатор, созданный из XElement, очевидно, не подходитв этой категории наблюдаемая проблема наблюдается.

Решение :

Изменение:

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

на:

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

Вот полный код, который был проверенработать как положено :

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);
            } 
        }
    }
}
0 голосов
/ 12 сентября 2011

Я воспроизвел твой результат. Мой входной XML содержит 2 пространства имен, в выходных XML пространства имен определены в другом порядке. Вы можете проверить свой выходной байт за байтом и найти различия.

...