PageRenderTime 8ms CodeModel.GetById 4ms app.highlight 53ms RepoModel.GetById 1ms app.codeStats 1ms

/desktop_clients/Visual Studio/Crear beneficiarios/Json100r3/Source/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs

https://bitbucket.org/wfpcoslv/maps-examples
C# | 3123 lines | 2643 code | 422 blank | 58 comment | 27 complexity | 94c7e6c587552f6fc1bac475d5194f38 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1#region License
   2// Copyright (c) 2007 James Newton-King
   3//
   4// Permission is hereby granted, free of charge, to any person
   5// obtaining a copy of this software and associated documentation
   6// files (the "Software"), to deal in the Software without
   7// restriction, including without limitation the rights to use,
   8// copy, modify, merge, publish, distribute, sublicense, and/or sell
   9// copies of the Software, and to permit persons to whom the
  10// Software is furnished to do so, subject to the following
  11// conditions:
  12//
  13// The above copyright notice and this permission notice shall be
  14// included in all copies or substantial portions of the Software.
  15//
  16// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  18// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  19// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  20// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  21// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  23// OTHER DEALINGS IN THE SOFTWARE.
  24#endregion
  25
  26#if !(DNXCORE50 || PORTABLE40)
  27using System.Globalization;
  28#if NET20
  29using Newtonsoft.Json.Utilities.LinqBridge;
  30#else
  31using System.Linq;
  32#endif
  33using System.Text;
  34using System;
  35using System.Collections.Generic;
  36using Newtonsoft.Json.Tests.Serialization;
  37using Newtonsoft.Json.Tests.TestObjects;
  38#if DNXCORE50
  39using Xunit;
  40using Test = Xunit.FactAttribute;
  41using Assert = Newtonsoft.Json.Tests.XUnitAssert;
  42#else
  43using NUnit.Framework;
  44#endif
  45using Newtonsoft.Json;
  46using System.IO;
  47using System.Xml;
  48using Newtonsoft.Json.Converters;
  49using Newtonsoft.Json.Utilities;
  50using Newtonsoft.Json.Linq;
  51#if !NET20
  52using System.Xml.Linq;
  53
  54#endif
  55
  56namespace Newtonsoft.Json.Tests.Converters
  57{
  58    [TestFixture]
  59    public class XmlNodeConverterTest : TestFixtureBase
  60    {
  61#if !PORTABLE || NETSTANDARD1_3
  62        private string SerializeXmlNode(XmlNode node)
  63        {
  64            string json = JsonConvert.SerializeXmlNode(node, Formatting.Indented);
  65
  66#if !(NET20)
  67#if !NETSTANDARD1_3
  68            XmlReader reader = new XmlNodeReader(node);
  69#else
  70            StringReader sr = new StringReader(node.OuterXml);
  71            XmlReader reader = XmlReader.Create(sr);
  72#endif
  73
  74            XObject xNode;
  75            if (node is XmlDocument)
  76            {
  77                xNode = XDocument.Load(reader);
  78            }
  79            else if (node is XmlAttribute)
  80            {
  81                XmlAttribute attribute = (XmlAttribute)node;
  82                xNode = new XAttribute(XName.Get(attribute.LocalName, attribute.NamespaceURI), attribute.Value);
  83            }
  84            else
  85            {
  86                reader.MoveToContent();
  87                xNode = XNode.ReadFrom(reader);
  88            }
  89
  90            string linqJson = JsonConvert.SerializeXNode(xNode, Formatting.Indented);
  91
  92            Assert.AreEqual(json, linqJson);
  93#endif
  94
  95            return json;
  96        }
  97
  98        private XmlNode DeserializeXmlNode(string json)
  99        {
 100            return DeserializeXmlNode(json, null);
 101        }
 102
 103        private XmlNode DeserializeXmlNode(string json, string deserializeRootElementName)
 104        {
 105            JsonTextReader reader;
 106
 107            reader = new JsonTextReader(new StringReader(json));
 108            reader.Read();
 109            XmlNodeConverter converter = new XmlNodeConverter();
 110            if (deserializeRootElementName != null)
 111            {
 112                converter.DeserializeRootElementName = deserializeRootElementName;
 113            }
 114
 115            XmlNode node = (XmlNode)converter.ReadJson(reader, typeof(XmlDocument), null, new JsonSerializer());
 116
 117#if !NET20
 118            string xmlText = node.OuterXml;
 119
 120            reader = new JsonTextReader(new StringReader(json));
 121            reader.Read();
 122            XDocument d = (XDocument)converter.ReadJson(reader, typeof(XDocument), null, new JsonSerializer());
 123
 124            string linqXmlText = d.ToString(SaveOptions.DisableFormatting);
 125            if (d.Declaration != null)
 126            {
 127                linqXmlText = d.Declaration + linqXmlText;
 128            }
 129
 130            Assert.AreEqual(xmlText, linqXmlText);
 131#endif
 132
 133            return node;
 134        }
 135#endif
 136
 137        private string IndentXml(string xml)
 138        {
 139            XmlReader reader = XmlReader.Create(new StringReader(xml));
 140
 141            StringWriter sw = new StringWriter();
 142            XmlWriter writer = XmlWriter.Create(sw, new XmlWriterSettings { Indent = true, OmitXmlDeclaration = true });
 143
 144            while (reader.Read())
 145            {
 146                writer.WriteNode(reader, false);
 147            }
 148
 149            writer.Flush();
 150
 151            return sw.ToString();
 152        }
 153
 154#if !NET20
 155        [Test]
 156        public void SerializeDollarProperty()
 157        {
 158            string json1 = @"{""$"":""test""}";
 159
 160            var doc = JsonConvert.DeserializeXNode(json1);
 161
 162            Assert.AreEqual(@"<_x0024_>test</_x0024_>", doc.ToString());
 163
 164            var json2 = JsonConvert.SerializeXNode(doc);
 165            
 166            Assert.AreEqual(json1, json2);
 167        }
 168
 169        [Test]
 170        public void SerializeNonKnownDollarProperty()
 171        {
 172            string json1 = @"{""$JELLY"":""test""}";
 173
 174            var doc = JsonConvert.DeserializeXNode(json1);
 175
 176            Console.WriteLine(doc.ToString());
 177
 178            Assert.AreEqual(@"<_x0024_JELLY>test</_x0024_JELLY>", doc.ToString());
 179
 180            var json2 = JsonConvert.SerializeXNode(doc);
 181
 182            Assert.AreEqual(json1, json2);
 183        }
 184
 185        public class MyModel
 186        {
 187            public string MyProperty { get; set; }
 188        }
 189
 190        [Test]
 191        public void ConvertNullString()
 192        {
 193            JObject json = new JObject();
 194            json["Prop1"] = (string)null;
 195            json["Prop2"] = new MyModel().MyProperty;
 196
 197            var xmlNodeConverter = new XmlNodeConverter { DeserializeRootElementName = "object" };
 198            var jsonSerializerSettings = new JsonSerializerSettings { Converters = new JsonConverter[] { xmlNodeConverter } };
 199            var jsonSerializer = JsonSerializer.CreateDefault(jsonSerializerSettings);
 200            XDocument d = json.ToObject<XDocument>(jsonSerializer);
 201
 202            StringAssert.Equals(@"<object>
 203  <Prop1 />
 204  <Prop2 />
 205</object>", d.ToString());
 206        }
 207
 208        public class Foo
 209        {
 210            public XElement Bar { get; set; }
 211        }
 212
 213        [Test]
 214        public void SerializeAndDeserializeXElement()
 215        {
 216            Foo foo = new Foo { Bar = null };
 217            string json = JsonConvert.SerializeObject(foo);
 218
 219            Assert.AreEqual(@"{""Bar"":null}", json);
 220            Foo foo2 = JsonConvert.DeserializeObject<Foo>(json);
 221
 222            Assert.IsNull(foo2.Bar);
 223        }
 224
 225        [Test]
 226        public void MultipleNamespacesXDocument()
 227        {
 228            string xml = @"<result xp_0:end=""2014-08-15 13:12:11.9184"" xp_0:start=""2014-08-15 13:11:49.3140"" xp_0:time_diff=""22604.3836"" xmlns:xp_0=""Test1"" p2:end=""2014-08-15 13:13:49.5522"" p2:start=""2014-08-15 13:13:49.0268"" p2:time_diff=""525.4646"" xmlns:p2=""Test2"" />";
 229
 230            XDocument d = XDocument.Parse(xml);
 231
 232            string json = JsonConvert.SerializeObject(d, Formatting.Indented);
 233
 234            StringAssert.AreEqual(@"{
 235  ""result"": {
 236    ""@xp_0:end"": ""2014-08-15 13:12:11.9184"",
 237    ""@xp_0:start"": ""2014-08-15 13:11:49.3140"",
 238    ""@xp_0:time_diff"": ""22604.3836"",
 239    ""@xmlns:xp_0"": ""Test1"",
 240    ""@p2:end"": ""2014-08-15 13:13:49.5522"",
 241    ""@p2:start"": ""2014-08-15 13:13:49.0268"",
 242    ""@p2:time_diff"": ""525.4646"",
 243    ""@xmlns:p2"": ""Test2""
 244  }
 245}", json);
 246
 247            XDocument doc = JsonConvert.DeserializeObject<XDocument>(json);
 248
 249            StringAssert.AreEqual(xml, doc.ToString());
 250        }
 251#endif
 252
 253#if !PORTABLE || NETSTANDARD1_3
 254        [Test]
 255        public void MultipleNamespacesXmlDocument()
 256        {
 257            string xml = @"<result xp_0:end=""2014-08-15 13:12:11.9184"" xp_0:start=""2014-08-15 13:11:49.3140"" xp_0:time_diff=""22604.3836"" xmlns:xp_0=""Test1"" p2:end=""2014-08-15 13:13:49.5522"" p2:start=""2014-08-15 13:13:49.0268"" p2:time_diff=""525.4646"" xmlns:p2=""Test2"" />";
 258
 259            XmlDocument d = new XmlDocument();
 260            d.LoadXml(xml);
 261
 262            string json = JsonConvert.SerializeObject(d, Formatting.Indented);
 263
 264            StringAssert.AreEqual(@"{
 265  ""result"": {
 266    ""@xp_0:end"": ""2014-08-15 13:12:11.9184"",
 267    ""@xp_0:start"": ""2014-08-15 13:11:49.3140"",
 268    ""@xp_0:time_diff"": ""22604.3836"",
 269    ""@xmlns:xp_0"": ""Test1"",
 270    ""@p2:end"": ""2014-08-15 13:13:49.5522"",
 271    ""@p2:start"": ""2014-08-15 13:13:49.0268"",
 272    ""@p2:time_diff"": ""525.4646"",
 273    ""@xmlns:p2"": ""Test2""
 274  }
 275}", json);
 276
 277            XmlDocument doc = JsonConvert.DeserializeObject<XmlDocument>(json);
 278
 279            StringAssert.AreEqual(xml, doc.OuterXml);
 280        }
 281
 282        [Test]
 283        public void SerializeXmlElement()
 284        {
 285            string xml = @"<payload>
 286    <Country>6</Country>
 287    <FinancialTransactionApprovalRequestUID>79</FinancialTransactionApprovalRequestUID>
 288    <TransactionStatus>Approved</TransactionStatus>
 289    <StatusChangeComment></StatusChangeComment>
 290    <RequestedBy>Someone</RequestedBy>
 291</payload>";
 292
 293            var xmlDocument = new XmlDocument();
 294
 295            xmlDocument.LoadXml(xml);
 296
 297            var result = xmlDocument.FirstChild.ChildNodes.Cast<XmlNode>().ToArray();
 298
 299            var json = JsonConvert.SerializeObject(result, Formatting.Indented); // <--- fails here with the cast message
 300
 301            StringAssert.AreEqual(@"[
 302  {
 303    ""Country"": ""6""
 304  },
 305  {
 306    ""FinancialTransactionApprovalRequestUID"": ""79""
 307  },
 308  {
 309    ""TransactionStatus"": ""Approved""
 310  },
 311  {
 312    ""StatusChangeComment"": """"
 313  },
 314  {
 315    ""RequestedBy"": ""Someone""
 316  }
 317]", json);
 318        }
 319#endif
 320
 321#if !NET20
 322        [Test]
 323        public void SerializeXElement()
 324        {
 325            string xml = @"<payload>
 326    <Country>6</Country>
 327    <FinancialTransactionApprovalRequestUID>79</FinancialTransactionApprovalRequestUID>
 328    <TransactionStatus>Approved</TransactionStatus>
 329    <StatusChangeComment></StatusChangeComment>
 330    <RequestedBy>Someone</RequestedBy>
 331</payload>";
 332
 333            var xmlDocument = XDocument.Parse(xml);
 334
 335            var result = xmlDocument.Root.Nodes().ToArray();
 336
 337            var json = JsonConvert.SerializeObject(result, Formatting.Indented); // <--- fails here with the cast message
 338
 339            StringAssert.AreEqual(@"[
 340  {
 341    ""Country"": ""6""
 342  },
 343  {
 344    ""FinancialTransactionApprovalRequestUID"": ""79""
 345  },
 346  {
 347    ""TransactionStatus"": ""Approved""
 348  },
 349  {
 350    ""StatusChangeComment"": """"
 351  },
 352  {
 353    ""RequestedBy"": ""Someone""
 354  }
 355]", json);
 356        }
 357
 358        public class DecimalContainer
 359        {
 360            public decimal Number { get; set; }
 361        }
 362
 363        [Test]
 364        public void FloatParseHandlingDecimal()
 365        {
 366            decimal d = (decimal)Math.PI + 1000000000m;
 367            var x = new DecimalContainer { Number = d };
 368
 369            var json = JsonConvert.SerializeObject(x, Formatting.Indented);
 370
 371            XDocument doc1 = JsonConvert.DeserializeObject<XDocument>(json, new JsonSerializerSettings
 372            {
 373                Converters = { new XmlNodeConverter() },
 374                FloatParseHandling = FloatParseHandling.Decimal
 375            });
 376
 377            var xml = doc1.ToString();
 378            Assert.AreEqual("<Number>1000000003.14159265358979</Number>", xml);
 379
 380            string json2 = JsonConvert.SerializeObject(doc1, Formatting.Indented);
 381
 382            DecimalContainer x2 = JsonConvert.DeserializeObject<DecimalContainer>(json2);
 383
 384            Assert.AreEqual(x.Number, x2.Number);
 385        }
 386
 387        public class DateTimeOffsetContainer
 388        {
 389            public DateTimeOffset Date { get; set; }
 390        }
 391
 392        [Test]
 393        public void DateTimeParseHandlingOffset()
 394        {
 395            DateTimeOffset d = new DateTimeOffset(2012, 12, 12, 12, 44, 1, TimeSpan.FromHours(12).Add(TimeSpan.FromMinutes(34)));
 396            var x = new DateTimeOffsetContainer { Date = d };
 397
 398            var json = JsonConvert.SerializeObject(x, Formatting.Indented);
 399
 400            XDocument doc1 = JsonConvert.DeserializeObject<XDocument>(json, new JsonSerializerSettings
 401            {
 402                Converters = { new XmlNodeConverter() },
 403                DateParseHandling = DateParseHandling.DateTimeOffset
 404            });
 405
 406            var xml = doc1.ToString();
 407            Assert.AreEqual("<Date>2012-12-12T12:44:01+12:34</Date>", xml);
 408
 409            string json2 = JsonConvert.SerializeObject(doc1, Formatting.Indented);
 410
 411            DateTimeOffsetContainer x2 = JsonConvert.DeserializeObject<DateTimeOffsetContainer>(json2);
 412
 413            Assert.AreEqual(x.Date, x2.Date);
 414        }
 415
 416        [Test]
 417        public void GroupElementsOfTheSameName()
 418        {
 419            string xml = "<root><p>Text1<span>Span1</span> <span>Span2</span> Text2</p></root>";
 420
 421            string json = JsonConvert.SerializeXNode(XElement.Parse(xml));
 422
 423            Assert.AreEqual(@"{""root"":{""p"":{""#text"":[""Text1"","" Text2""],""span"":[""Span1"",""Span2""]}}}", json);
 424
 425            XDocument doc = JsonConvert.DeserializeXNode(json);
 426
 427            StringAssert.AreEqual(@"<root>
 428  <p>Text1 Text2<span>Span1</span><span>Span2</span></p>
 429</root>", doc.ToString());
 430        }
 431
 432#if !PORTABLE || NETSTANDARD1_3
 433        [Test]
 434        public void SerializeEmptyDocument()
 435        {
 436            XmlDocument doc = new XmlDocument();
 437            doc.LoadXml("<root />");
 438
 439            string json = JsonConvert.SerializeXmlNode(doc, Formatting.Indented, true);
 440            Assert.AreEqual("null", json);
 441
 442            doc = new XmlDocument();
 443            doc.LoadXml("<root></root>");
 444
 445            json = JsonConvert.SerializeXmlNode(doc, Formatting.Indented, true);
 446            Assert.AreEqual(@"""""", json);
 447
 448            XDocument doc1 = XDocument.Parse("<root />");
 449
 450            json = JsonConvert.SerializeXNode(doc1, Formatting.Indented, true);
 451            Assert.AreEqual("null", json);
 452
 453            doc1 = XDocument.Parse("<root></root>");
 454
 455            json = JsonConvert.SerializeXNode(doc1, Formatting.Indented, true);
 456            Assert.AreEqual(@"""""", json);
 457        }
 458#endif
 459
 460        [Test]
 461        public void SerializeAndDeserializeXmlWithNamespaceInChildrenAndNoValueInChildren()
 462        {
 463            var xmlString = @"<root>
 464                              <b xmlns='http://www.example.com/ns'/>
 465                              <c>AAA</c>
 466                              <test>adad</test>
 467                              </root>";
 468
 469            var xml = XElement.Parse(xmlString);
 470
 471            var json1 = JsonConvert.SerializeXNode(xml);
 472            var xmlBack = JsonConvert.DeserializeObject<XElement>(json1);
 473
 474            var equals = XElement.DeepEquals(xmlBack, xml);
 475            Assert.IsTrue(equals);
 476        }
 477
 478#if !PORTABLE || NETSTANDARD1_3
 479        [Test]
 480        public void DeserializeUndeclaredNamespacePrefix()
 481        {
 482            XmlDocument doc = JsonConvert.DeserializeXmlNode("{ A: { '@xsi:nil': true } }");
 483
 484            Assert.AreEqual(@"<A nil=""true"" />", doc.OuterXml);
 485
 486            XDocument xdoc = JsonConvert.DeserializeXNode("{ A: { '@xsi:nil': true } }");
 487
 488            Assert.AreEqual(doc.OuterXml, xdoc.ToString());
 489        }
 490#endif
 491#endif
 492
 493#if !PORTABLE || NETSTANDARD1_3
 494        [Test]
 495        public void DeserializeMultipleRootElements()
 496        {
 497            string json = @"{
 498    ""Id"": 1,
 499     ""Email"": ""james@example.com"",
 500     ""Active"": true,
 501     ""CreatedDate"": ""2013-01-20T00:00:00Z"",
 502     ""Roles"": [
 503       ""User"",
 504       ""Admin""
 505     ],
 506    ""Team"": {
 507        ""Id"": 2,
 508        ""Name"": ""Software Developers"",
 509        ""Description"": ""Creators of fine software products and services.""
 510    }
 511}";
 512            ExceptionAssert.Throws<JsonSerializationException>(
 513                () => { JsonConvert.DeserializeXmlNode(json); },
 514                "JSON root object has multiple properties. The root object must have a single property in order to create a valid XML document. Consider specifying a DeserializeRootElementName. Path 'Email', line 3, position 13.");
 515        }
 516
 517        [Test]
 518        public void DocumentSerializeIndented()
 519        {
 520            string xml = @"<?xml version=""1.0"" standalone=""no""?>
 521<?xml-stylesheet href=""classic.xsl"" type=""text/xml""?>
 522<span class=""vevent"">
 523  <a class=""url"" href=""http://www.web2con.com/"">
 524    <span class=""summary"">Web 2.0 Conference<![CDATA[my escaped text]]></span>
 525    <abbr class=""dtstart"" title=""2005-10-05"">October 5</abbr>
 526    <abbr class=""dtend"" title=""2005-10-08"">7</abbr>
 527    <span class=""location"">Argent Hotel, San Francisco, CA</span>
 528  </a>
 529</span>";
 530            XmlDocument doc = new XmlDocument();
 531            doc.LoadXml(xml);
 532
 533            string jsonText = SerializeXmlNode(doc);
 534            string expected = @"{
 535  ""?xml"": {
 536    ""@version"": ""1.0"",
 537    ""@standalone"": ""no""
 538  },
 539  ""?xml-stylesheet"": ""href=\""classic.xsl\"" type=\""text/xml\"""",
 540  ""span"": {
 541    ""@class"": ""vevent"",
 542    ""a"": {
 543      ""@class"": ""url"",
 544      ""@href"": ""http://www.web2con.com/"",
 545      ""span"": [
 546        {
 547          ""@class"": ""summary"",
 548          ""#text"": ""Web 2.0 Conference"",
 549          ""#cdata-section"": ""my escaped text""
 550        },
 551        {
 552          ""@class"": ""location"",
 553          ""#text"": ""Argent Hotel, San Francisco, CA""
 554        }
 555      ],
 556      ""abbr"": [
 557        {
 558          ""@class"": ""dtstart"",
 559          ""@title"": ""2005-10-05"",
 560          ""#text"": ""October 5""
 561        },
 562        {
 563          ""@class"": ""dtend"",
 564          ""@title"": ""2005-10-08"",
 565          ""#text"": ""7""
 566        }
 567      ]
 568    }
 569  }
 570}";
 571
 572            StringAssert.AreEqual(expected, jsonText);
 573        }
 574
 575        [Test]
 576        public void SerializeNodeTypes()
 577        {
 578            XmlDocument doc = new XmlDocument();
 579            string jsonText;
 580
 581            string xml = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
 582<xs:schema xs:id=""SomeID"" 
 583	xmlns="""" 
 584	xmlns:xs=""http://www.w3.org/2001/XMLSchema"" 
 585	xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
 586	<xs:element name=""MyDataSet"" msdata:IsDataSet=""true"">
 587	</xs:element>
 588</xs:schema>";
 589
 590            XmlDocument document = new XmlDocument();
 591            document.LoadXml(xml);
 592
 593            // XmlAttribute
 594            XmlAttribute attribute = document.DocumentElement.ChildNodes[0].Attributes["IsDataSet", "urn:schemas-microsoft-com:xml-msdata"];
 595            attribute.Value = "true";
 596
 597            jsonText = JsonConvert.SerializeXmlNode(attribute);
 598
 599            Assert.AreEqual(@"{""@msdata:IsDataSet"":""true""}", jsonText);
 600
 601#if !NET20
 602            XDocument d = XDocument.Parse(xml);
 603            XAttribute a = d.Root.Element("{http://www.w3.org/2001/XMLSchema}element").Attribute("{urn:schemas-microsoft-com:xml-msdata}IsDataSet");
 604
 605            jsonText = JsonConvert.SerializeXNode(a);
 606
 607            Assert.AreEqual(@"{""@msdata:IsDataSet"":""true""}", jsonText);
 608#endif
 609
 610            // XmlProcessingInstruction
 611            XmlProcessingInstruction instruction = doc.CreateProcessingInstruction("xml-stylesheet", @"href=""classic.xsl"" type=""text/xml""");
 612
 613            jsonText = JsonConvert.SerializeXmlNode(instruction);
 614
 615            Assert.AreEqual(@"{""?xml-stylesheet"":""href=\""classic.xsl\"" type=\""text/xml\""""}", jsonText);
 616
 617            // XmlProcessingInstruction
 618            XmlCDataSection cDataSection = doc.CreateCDataSection("<Kiwi>true</Kiwi>");
 619
 620            jsonText = JsonConvert.SerializeXmlNode(cDataSection);
 621
 622            Assert.AreEqual(@"{""#cdata-section"":""<Kiwi>true</Kiwi>""}", jsonText);
 623
 624            // XmlElement
 625            XmlElement element = doc.CreateElement("xs", "Choice", "http://www.w3.org/2001/XMLSchema");
 626            element.SetAttributeNode(doc.CreateAttribute("msdata", "IsDataSet", "urn:schemas-microsoft-com:xml-msdata"));
 627
 628            XmlAttribute aa = doc.CreateAttribute(@"xmlns", "xs", "http://www.w3.org/2000/xmlns/");
 629            aa.Value = "http://www.w3.org/2001/XMLSchema";
 630            element.SetAttributeNode(aa);
 631
 632            aa = doc.CreateAttribute(@"xmlns", "msdata", "http://www.w3.org/2000/xmlns/");
 633            aa.Value = "urn:schemas-microsoft-com:xml-msdata";
 634            element.SetAttributeNode(aa);
 635
 636            element.AppendChild(instruction);
 637            element.AppendChild(cDataSection);
 638
 639            doc.AppendChild(element);
 640
 641            jsonText = JsonConvert.SerializeXmlNode(element, Formatting.Indented);
 642
 643            StringAssert.AreEqual(@"{
 644  ""xs:Choice"": {
 645    ""@msdata:IsDataSet"": """",
 646    ""@xmlns:xs"": ""http://www.w3.org/2001/XMLSchema"",
 647    ""@xmlns:msdata"": ""urn:schemas-microsoft-com:xml-msdata"",
 648    ""?xml-stylesheet"": ""href=\""classic.xsl\"" type=\""text/xml\"""",
 649    ""#cdata-section"": ""<Kiwi>true</Kiwi>""
 650  }
 651}", jsonText);
 652        }
 653
 654        [Test]
 655        public void SerializeNodeTypes_Encoding()
 656        {
 657            XmlNode node = DeserializeXmlNode(@"{
 658  ""xs!:Choice!"": {
 659    ""@msdata:IsDataSet!"": """",
 660    ""@xmlns:xs!"": ""http://www.w3.org/2001/XMLSchema"",
 661    ""@xmlns:msdata"": ""urn:schemas-microsoft-com:xml-msdata"",
 662    ""?xml-stylesheet"": ""href=\""classic.xsl\"" type=\""text/xml\"""",
 663    ""#cdata-section"": ""<Kiwi>true</Kiwi>""
 664  }
 665}");
 666
 667            Assert.AreEqual(@"<xs_x0021_:Choice_x0021_ msdata:IsDataSet_x0021_="""" xmlns:xs_x0021_=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata""><?xml-stylesheet href=""classic.xsl"" type=""text/xml""?><![CDATA[<Kiwi>true</Kiwi>]]></xs_x0021_:Choice_x0021_>", node.InnerXml);
 668
 669            string json = SerializeXmlNode(node);
 670
 671            StringAssert.AreEqual(@"{
 672  ""xs!:Choice!"": {
 673    ""@msdata:IsDataSet!"": """",
 674    ""@xmlns:xs!"": ""http://www.w3.org/2001/XMLSchema"",
 675    ""@xmlns:msdata"": ""urn:schemas-microsoft-com:xml-msdata"",
 676    ""?xml-stylesheet"": ""href=\""classic.xsl\"" type=\""text/xml\"""",
 677    ""#cdata-section"": ""<Kiwi>true</Kiwi>""
 678  }
 679}", json);
 680        }
 681
 682        [Test]
 683        public void DocumentFragmentSerialize()
 684        {
 685            XmlDocument doc = new XmlDocument();
 686
 687            XmlDocumentFragment fragement = doc.CreateDocumentFragment();
 688
 689            fragement.InnerXml = "<Item>widget</Item><Item>widget</Item>";
 690
 691            string jsonText = JsonConvert.SerializeXmlNode(fragement);
 692
 693            string expected = @"{""Item"":[""widget"",""widget""]}";
 694
 695            Assert.AreEqual(expected, jsonText);
 696        }
 697
 698#if !NETSTANDARD1_3
 699        [Test]
 700        public void XmlDocumentTypeSerialize()
 701        {
 702            string xml = @"<?xml version=""1.0"" encoding=""utf-8""?><!DOCTYPE STOCKQUOTE PUBLIC ""-//W3C//DTD StockQuote 1.5//EN"" ""http://www.idontexistnopenopewhatnope123.org/dtd/stockquote_1.5.dtd""><STOCKQUOTE ROWCOUNT=""2""><RESULT><ROW><ASK>0</ASK><BID>0</BID><CHANGE>-16.310</CHANGE><COMPANYNAME>Dow Jones</COMPANYNAME><DATETIME>2014-04-17 15:50:37</DATETIME><DIVIDEND>0</DIVIDEND><EPS>0</EPS><EXCHANGE></EXCHANGE><HIGH>16460.490</HIGH><LASTDATETIME>2014-04-17 15:50:37</LASTDATETIME><LASTPRICE>16408.540</LASTPRICE><LOW>16368.140</LOW><OPEN>16424.140</OPEN><PCHANGE>-0.099</PCHANGE><PE>0</PE><PREVIOUSCLOSE>16424.850</PREVIOUSCLOSE><SHARES>0</SHARES><TICKER>DJII</TICKER><TRADES>0</TRADES><VOLUME>136188700</VOLUME><YEARHIGH>11309.000</YEARHIGH><YEARLOW>9302.280</YEARLOW><YIELD>0</YIELD></ROW><ROW><ASK>0</ASK><BID>0</BID><CHANGE>9.290</CHANGE><COMPANYNAME>NASDAQ</COMPANYNAME><DATETIME>2014-04-17 15:40:01</DATETIME><DIVIDEND>0</DIVIDEND><EPS>0</EPS><EXCHANGE></EXCHANGE><HIGH>4110.460</HIGH><LASTDATETIME>2014-04-17 15:40:01</LASTDATETIME><LASTPRICE>4095.520</LASTPRICE><LOW>4064.700</LOW><OPEN>4080.300</OPEN><PCHANGE>0.227</PCHANGE><PE>0</PE><PREVIOUSCLOSE>4086.230</PREVIOUSCLOSE><SHARES>0</SHARES><TICKER>COMP</TICKER><TRADES>0</TRADES><VOLUME>1784210100</VOLUME><YEARHIGH>4371.710</YEARHIGH><YEARLOW>3154.960</YEARLOW><YIELD>0</YIELD></ROW></RESULT><STATUS>Couldn't find ticker: SPIC?</STATUS><STATUSCODE>2</STATUSCODE></STOCKQUOTE>";
 703
 704            string expected = @"{
 705  ""?xml"": {
 706    ""@version"": ""1.0"",
 707    ""@encoding"": ""utf-8""
 708  },
 709  ""!DOCTYPE"": {
 710    ""@name"": ""STOCKQUOTE"",
 711    ""@public"": ""-//W3C//DTD StockQuote 1.5//EN"",
 712    ""@system"": ""http://www.idontexistnopenopewhatnope123.org/dtd/stockquote_1.5.dtd""
 713  },
 714  ""STOCKQUOTE"": {
 715    ""@ROWCOUNT"": ""2"",
 716    ""RESULT"": {
 717      ""ROW"": [
 718        {
 719          ""ASK"": ""0"",
 720          ""BID"": ""0"",
 721          ""CHANGE"": ""-16.310"",
 722          ""COMPANYNAME"": ""Dow Jones"",
 723          ""DATETIME"": ""2014-04-17 15:50:37"",
 724          ""DIVIDEND"": ""0"",
 725          ""EPS"": ""0"",
 726          ""EXCHANGE"": """",
 727          ""HIGH"": ""16460.490"",
 728          ""LASTDATETIME"": ""2014-04-17 15:50:37"",
 729          ""LASTPRICE"": ""16408.540"",
 730          ""LOW"": ""16368.140"",
 731          ""OPEN"": ""16424.140"",
 732          ""PCHANGE"": ""-0.099"",
 733          ""PE"": ""0"",
 734          ""PREVIOUSCLOSE"": ""16424.850"",
 735          ""SHARES"": ""0"",
 736          ""TICKER"": ""DJII"",
 737          ""TRADES"": ""0"",
 738          ""VOLUME"": ""136188700"",
 739          ""YEARHIGH"": ""11309.000"",
 740          ""YEARLOW"": ""9302.280"",
 741          ""YIELD"": ""0""
 742        },
 743        {
 744          ""ASK"": ""0"",
 745          ""BID"": ""0"",
 746          ""CHANGE"": ""9.290"",
 747          ""COMPANYNAME"": ""NASDAQ"",
 748          ""DATETIME"": ""2014-04-17 15:40:01"",
 749          ""DIVIDEND"": ""0"",
 750          ""EPS"": ""0"",
 751          ""EXCHANGE"": """",
 752          ""HIGH"": ""4110.460"",
 753          ""LASTDATETIME"": ""2014-04-17 15:40:01"",
 754          ""LASTPRICE"": ""4095.520"",
 755          ""LOW"": ""4064.700"",
 756          ""OPEN"": ""4080.300"",
 757          ""PCHANGE"": ""0.227"",
 758          ""PE"": ""0"",
 759          ""PREVIOUSCLOSE"": ""4086.230"",
 760          ""SHARES"": ""0"",
 761          ""TICKER"": ""COMP"",
 762          ""TRADES"": ""0"",
 763          ""VOLUME"": ""1784210100"",
 764          ""YEARHIGH"": ""4371.710"",
 765          ""YEARLOW"": ""3154.960"",
 766          ""YIELD"": ""0""
 767        }
 768      ]
 769    },
 770    ""STATUS"": ""Couldn't find ticker: SPIC?"",
 771    ""STATUSCODE"": ""2""
 772  }
 773}";
 774
 775            XmlDocument doc1 = new XmlDocument();
 776            doc1.XmlResolver = null;
 777            doc1.LoadXml(xml);
 778
 779            string json1 = JsonConvert.SerializeXmlNode(doc1, Formatting.Indented);
 780
 781            StringAssert.AreEqual(expected, json1);
 782
 783            XmlDocument doc11 = JsonConvert.DeserializeXmlNode(json1);
 784
 785            StringAssert.AreEqual(xml, ToStringWithDeclaration(doc11));
 786
 787#if !NET20
 788            XDocument doc2 = XDocument.Parse(xml);
 789
 790            string json2 = JsonConvert.SerializeXNode(doc2, Formatting.Indented);
 791
 792            StringAssert.AreEqual(expected, json2);
 793
 794            XDocument doc22 = JsonConvert.DeserializeXNode(json2);
 795
 796            StringAssert.AreEqual(xml, ToStringWithDeclaration(doc22));
 797#endif
 798        }
 799#endif
 800
 801        public class Utf8StringWriter : StringWriter
 802        {
 803            public override Encoding Encoding
 804            {
 805                get { return Encoding.UTF8; }
 806            }
 807
 808            public Utf8StringWriter(StringBuilder sb) : base(sb)
 809            {
 810            }
 811        }
 812
 813#if !NET20
 814        public static string ToStringWithDeclaration(XDocument doc, bool indent = false)
 815        {
 816            StringBuilder builder = new StringBuilder();
 817            using (var writer = XmlWriter.Create(new Utf8StringWriter(builder), new XmlWriterSettings { Indent = indent }))
 818            {
 819                doc.Save(writer);
 820            }
 821            return builder.ToString();
 822        }
 823#endif
 824
 825        public static string ToStringWithDeclaration(XmlDocument doc, bool indent = false)
 826        {
 827            StringBuilder builder = new StringBuilder();
 828            using (var writer = XmlWriter.Create(new Utf8StringWriter(builder), new XmlWriterSettings { Indent = indent }))
 829            {
 830                doc.Save(writer);
 831            }
 832            return builder.ToString();
 833        }
 834
 835        [Test]
 836        public void NamespaceSerializeDeserialize()
 837        {
 838            string xml = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
 839<xs:schema xs:id=""SomeID"" 
 840	xmlns="""" 
 841	xmlns:xs=""http://www.w3.org/2001/XMLSchema"" 
 842	xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
 843	<xs:element name=""MyDataSet"" msdata:IsDataSet=""true"">
 844		<xs:complexType>
 845			<xs:choice maxOccurs=""unbounded"">
 846				<xs:element name=""customers"" >
 847					<xs:complexType >
 848						<xs:sequence>
 849							<xs:element name=""CustomerID"" type=""xs:integer"" 
 850										 minOccurs=""0"" />
 851							<xs:element name=""CompanyName"" type=""xs:string"" 
 852										 minOccurs=""0"" />
 853							<xs:element name=""Phone"" type=""xs:string"" />
 854						</xs:sequence>
 855					</xs:complexType>
 856				</xs:element>
 857			</xs:choice>
 858		</xs:complexType>
 859	</xs:element>
 860</xs:schema>";
 861
 862            XmlDocument doc = new XmlDocument();
 863            doc.LoadXml(xml);
 864
 865            string jsonText = SerializeXmlNode(doc);
 866
 867            string expected = @"{
 868  ""?xml"": {
 869    ""@version"": ""1.0"",
 870    ""@encoding"": ""utf-8""
 871  },
 872  ""xs:schema"": {
 873    ""@xs:id"": ""SomeID"",
 874    ""@xmlns"": """",
 875    ""@xmlns:xs"": ""http://www.w3.org/2001/XMLSchema"",
 876    ""@xmlns:msdata"": ""urn:schemas-microsoft-com:xml-msdata"",
 877    ""xs:element"": {
 878      ""@name"": ""MyDataSet"",
 879      ""@msdata:IsDataSet"": ""true"",
 880      ""xs:complexType"": {
 881        ""xs:choice"": {
 882          ""@maxOccurs"": ""unbounded"",
 883          ""xs:element"": {
 884            ""@name"": ""customers"",
 885            ""xs:complexType"": {
 886              ""xs:sequence"": {
 887                ""xs:element"": [
 888                  {
 889                    ""@name"": ""CustomerID"",
 890                    ""@type"": ""xs:integer"",
 891                    ""@minOccurs"": ""0""
 892                  },
 893                  {
 894                    ""@name"": ""CompanyName"",
 895                    ""@type"": ""xs:string"",
 896                    ""@minOccurs"": ""0""
 897                  },
 898                  {
 899                    ""@name"": ""Phone"",
 900                    ""@type"": ""xs:string""
 901                  }
 902                ]
 903              }
 904            }
 905          }
 906        }
 907      }
 908    }
 909  }
 910}";
 911
 912            StringAssert.AreEqual(expected, jsonText);
 913
 914            XmlDocument deserializedDoc = (XmlDocument)DeserializeXmlNode(jsonText);
 915
 916            Assert.AreEqual(doc.InnerXml, deserializedDoc.InnerXml);
 917        }
 918
 919        [Test]
 920        public void FailOnIncomplete()
 921        {
 922            string json = @"{'Row' : ";
 923
 924            ExceptionAssert.Throws<JsonSerializationException>(
 925                () => JsonConvert.DeserializeXmlNode(json, "ROOT"),
 926                "Unexpected end when reading JSON. Path 'Row', line 1, position 9.");
 927        }
 928
 929        [Test]
 930        public void DocumentDeserialize()
 931        {
 932            string jsonText = @"{
 933  ""?xml"": {
 934    ""@version"": ""1.0"",
 935    ""@standalone"": ""no""
 936  },
 937  ""span"": {
 938    ""@class"": ""vevent"",
 939    ""a"": {
 940      ""@class"": ""url"",
 941      ""span"": {
 942        ""@class"": ""summary"",
 943        ""#text"": ""Web 2.0 Conference"",
 944        ""#cdata-section"": ""my escaped text""
 945      },
 946      ""@href"": ""http://www.web2con.com/""
 947    }
 948  }
 949}";
 950
 951            XmlDocument doc = (XmlDocument)DeserializeXmlNode(jsonText);
 952
 953            string expected = @"<?xml version=""1.0"" standalone=""no""?>
 954<span class=""vevent"">
 955  <a class=""url"" href=""http://www.web2con.com/"">
 956    <span class=""summary"">Web 2.0 Conference<![CDATA[my escaped text]]></span>
 957  </a>
 958</span>";
 959
 960            string formattedXml = GetIndentedInnerXml(doc);
 961
 962            StringAssert.AreEqual(expected, formattedXml);
 963        }
 964
 965        private string GetIndentedInnerXml(XmlNode node)
 966        {
 967            XmlWriterSettings settings = new XmlWriterSettings();
 968            settings.Indent = true;
 969
 970            StringWriter sw = new StringWriter();
 971
 972            using (XmlWriter writer = XmlWriter.Create(sw, settings))
 973            {
 974                node.WriteTo(writer);
 975            }
 976
 977            return sw.ToString();
 978        }
 979
 980        public class Foo2
 981        {
 982            public XmlElement Bar { get; set; }
 983        }
 984
 985        [Test]
 986        public void SerializeAndDeserializeXmlElement()
 987        {
 988            Foo2 foo = new Foo2 { Bar = null };
 989            string json = JsonConvert.SerializeObject(foo);
 990
 991            Assert.AreEqual(@"{""Bar"":null}", json);
 992            Foo2 foo2 = JsonConvert.DeserializeObject<Foo2>(json);
 993
 994            Assert.IsNull(foo2.Bar);
 995        }
 996
 997        [Test]
 998        public void SingleTextNode()
 999        {
1000            string xml = @"<?xml version=""1.0"" standalone=""no""?>
1001			<root>
1002			  <person id=""1"">
1003	  			<name>Alan</name>
1004		  		<url>http://www.google.com</url>
1005			  </person>
1006			  <person id=""2"">
1007			  	<name>Louis</name>
1008				  <url>http://www.yahoo.com</url>
1009			  </person>
1010			</root>";
1011
1012            XmlDocument doc = new XmlDocument();
1013            doc.LoadXml(xml);
1014
1015            string jsonText = SerializeXmlNode(doc);
1016
1017            XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText);
1018
1019            Assert.AreEqual(doc.InnerXml, newDoc.InnerXml);
1020        }
1021
1022        [Test]
1023        public void EmptyNode()
1024        {
1025            string xml = @"<?xml version=""1.0"" standalone=""no""?>
1026			<root>
1027			  <person id=""1"">
1028				<name>Alan</name>
1029				<url />
1030			  </person>
1031			  <person id=""2"">
1032				<name>Louis</name>
1033				<url>http://www.yahoo.com</url>
1034			  </person>
1035			</root>";
1036
1037            XmlDocument doc = new XmlDocument();
1038            doc.LoadXml(xml);
1039
1040            string jsonText = SerializeXmlNode(doc);
1041
1042            StringAssert.AreEqual(@"{
1043  ""?xml"": {
1044    ""@version"": ""1.0"",
1045    ""@standalone"": ""no""
1046  },
1047  ""root"": {
1048    ""person"": [
1049      {
1050        ""@id"": ""1"",
1051        ""name"": ""Alan"",
1052        ""url"": null
1053      },
1054      {
1055        ""@id"": ""2"",
1056        ""name"": ""Louis"",
1057        ""url"": ""http://www.yahoo.com""
1058      }
1059    ]
1060  }
1061}", jsonText);
1062
1063            XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText);
1064
1065            Assert.AreEqual(doc.InnerXml, newDoc.InnerXml);
1066        }
1067
1068        [Test]
1069        public void OtherElementDataTypes()
1070        {
1071            string jsonText = @"{""?xml"":{""@version"":""1.0"",""@standalone"":""no""},""root"":{""person"":[{""@id"":""1"",""Float"":2.5,""Integer"":99},{""Boolean"":true,""@id"":""2"",""date"":""\/Date(954374400000)\/""}]}}";
1072
1073            XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText);
1074
1075            string expected = @"<?xml version=""1.0"" standalone=""no""?><root><person id=""1""><Float>2.5</Float><Integer>99</Integer></person><person id=""2""><Boolean>true</Boolean><date>2000-03-30T00:00:00Z</date></person></root>";
1076
1077            Assert.AreEqual(expected, newDoc.InnerXml);
1078        }
1079
1080        [Test]
1081        public void NoRootObject()
1082        {
1083            ExceptionAssert.Throws<JsonSerializationException>(() => { XmlDocument newDoc = (XmlDocument)JsonConvert.DeserializeXmlNode(@"[1]"); }, "XmlNodeConverter can only convert JSON that begins with an object. Path '', line 1, position 1.");
1084        }
1085
1086        [Test]
1087        public void RootObjectMultipleProperties()
1088        {
1089            ExceptionAssert.Throws<JsonSerializationException>(
1090                () => { XmlDocument newDoc = (XmlDocument)JsonConvert.DeserializeXmlNode(@"{Prop1:1,Prop2:2}"); },
1091                "JSON root object has multiple properties. The root object must have a single property in order to create a valid XML document. Consider specifying a DeserializeRootElementName. Path 'Prop2', line 1, position 15.");
1092        }
1093
1094        [Test]
1095        public void JavaScriptConstructor()
1096        {
1097            string jsonText = @"{root:{r:new Date(34343, 55)}}";
1098
1099            XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText);
1100
1101            string expected = @"<root><r><Date>34343</Date><Date>55</Date></r></root>";
1102
1103            Assert.AreEqual(expected, newDoc.InnerXml);
1104
1105            string json = SerializeXmlNode(newDoc);
1106            expected = @"{
1107  ""root"": {
1108    ""r"": {
1109      ""Date"": [
1110        ""34343"",
1111        ""55""
1112      ]
1113    }
1114  }
1115}";
1116
1117            StringAssert.AreEqual(expected, json);
1118        }
1119
1120        [Test]
1121        public void ForceJsonArray()
1122        {
1123            string arrayXml = @"<root xmlns:json=""http://james.newtonking.com/projects/json"">
1124			  <person id=""1"">
1125				  <name>Alan</name>
1126				  <url>http://www.google.com</url>
1127				  <role json:Array=""true"">Admin</role>
1128			  </person>
1129			</root>";
1130
1131            XmlDocument arrayDoc = new XmlDocument();
1132            arrayDoc.LoadXml(arrayXml);
1133
1134            string arrayJsonText = SerializeXmlNode(arrayDoc);
1135            string expected = @"{
1136  ""root"": {
1137    ""person"": {
1138      ""@id"": ""1"",
1139      ""name"": ""Alan"",
1140      ""url"": ""http://www.google.com"",
1141      ""role"": [
1142        ""Admin""
1143      ]
1144    }
1145  }
1146}";
1147            StringAssert.AreEqual(expected, arrayJsonText);
1148
1149            arrayXml = @"<root xmlns:json=""http://james.newtonking.com/projects/json"">
1150			  <person id=""1"">
1151				  <name>Alan</name>
1152				  <url>http://www.google.com</url>
1153				  <role json:Array=""true"">Admin1</role>
1154				  <role json:Array=""true"">Admin2</role>
1155			  </person>
1156			</root>";
1157
1158            arrayDoc = new XmlDocument();
1159            arrayDoc.LoadXml(arrayXml);
1160
1161            arrayJsonText = SerializeXmlNode(arrayDoc);
1162            expected = @"{
1163  ""root"": {
1164    ""person"": {
1165      ""@id"": ""1"",
1166      ""name"": ""Alan"",
1167      ""url"": ""http://www.google.com"",
1168      ""role"": [
1169        ""Admin1"",
1170        ""Admin2""
1171      ]
1172    }
1173  }
1174}";
1175            StringAssert.AreEqual(expected, arrayJsonText);
1176
1177            arrayXml = @"<root xmlns:json=""http://james.newtonking.com/projects/json"">
1178			  <person id=""1"">
1179				  <name>Alan</name>
1180				  <url>http://www.google.com</url>
1181				  <role json:Array=""false"">Admin1</role>
1182			  </person>
1183			</root>";
1184
1185            arrayDoc = new XmlDocument();
1186            arrayDoc.LoadXml(arrayXml);
1187
1188            arrayJsonText = SerializeXmlNode(arrayDoc);
1189            expected = @"{
1190  ""root"": {
1191    ""person"": {
1192      ""@id"": ""1"",
1193      ""name"": ""Alan"",
1194      ""url"": ""http://www.google.com"",
1195      ""role"": ""Admin1""
1196    }
1197  }
1198}";
1199            StringAssert.AreEqual(expected, arrayJsonText);
1200
1201            arrayXml = @"<root>
1202			  <person id=""1"">
1203				  <name>Alan</name>
1204				  <url>http://www.google.com</url>
1205				  <role json:Array=""true"" xmlns:json=""http://james.newtonking.com/projects/json"">Admin</role>
1206			  </person>
1207			</root>";
1208
1209            arrayDoc = new XmlDocument();
1210            arrayDoc.LoadXml(arrayXml);
1211
1212            arrayJsonText = SerializeXmlNode(arrayDoc);
1213            expected = @"{
1214  ""root"": {
1215    ""person"": {
1216      ""@id"": ""1"",
1217      ""name"": ""Alan"",
1218      ""url"": ""http://www.google.com"",
1219      ""role"": [
1220        ""Admin""
1221      ]
1222    }
1223  }
1224}";
1225            StringAssert.AreEqual(expected, arrayJsonText);
1226        }
1227
1228        [Test]
1229        public void MultipleRootPropertiesXmlDocument()
1230        {
1231            string json = @"{""count"": 773840,""photos"": null}";
1232
1233            ExceptionAssert.Throws<JsonSerializationException>(
1234                () => { JsonConvert.DeserializeXmlNode(json); },
1235                "JSON root object has multiple properties. The root object must have a single property in order to create a valid XML document. Consider specifying a DeserializeRootElementName. Path 'photos', line 1, position 26.");
1236        }
1237#endif
1238
1239#if !NET20
1240        [Test]
1241        public void MultipleRootPropertiesXDocument()
1242        {
1243            string json = @"{""count"": 773840,""photos"": null}";
1244
1245            ExceptionAssert.Throws<JsonSerializationException>(
1246                () => { JsonConvert.DeserializeXNode(json); },
1247                "JSON root object has multiple properties. The root object must have a single property in order to create a valid XML document. Consider specifying a DeserializeRootElementName. Path 'photos', line 1, position 26.");
1248        }
1249#endif
1250
1251        [Test]
1252        public void MultipleRootPropertiesAddRootElement()
1253        {
1254            string json = @"{""count"": 773840,""photos"": 773840}";
1255
1256#if !PORTABLE
1257            XmlDocument newDoc = JsonConvert.DeserializeXmlNode(json, "myRoot");
1258
1259            Assert.AreEqual(@"<myRoot><count>773840</count><photos>773840</photos></myRoot>", newDoc.InnerXml);
1260#endif
1261
1262#if !NET20
1263            XDocument newXDoc = JsonConvert.DeserializeXNode(json, "myRoot");
1264
1265            Assert.AreEqual(@"<myRoot><count>773840</count><photos>773840</photos></myRoot>", newXDoc.ToString(SaveOptions.DisableFormatting));
1266#endif
1267        }
1268
1269        [Test]
1270        public void NestedArrays()
1271        {
1272            string json = @"{
1273  ""available_sizes"": [
1274    [
1275      ""assets/images/resized/0001/1070/11070v1-max-150x150.jpg"",
1276      ""assets/images/resized/0001/1070/11070v1-max-150x150.jpg""
1277    ],
1278    [
1279      ""assets/images/resized/0001/1070/11070v1-max-250x250.jpg"",
1280      ""assets/images/resized/0001/1070/11070v1-max-250x250.jpg""
1281    ],
1282    [
1283      ""assets/images/resized/0001/1070/11070v1-max-250x250.jpg""
1284    ]
1285  ]
1286}";
1287
1288#if !PORTABLE || NETSTANDARD1_3
1289            XmlDocument newDoc = JsonConvert.DeserializeXmlNode(json, "myRoot");
1290
1291            string xml = IndentXml(newDoc.InnerXml);
1292
1293            StringAssert.AreEqual(@"<myRoot>
1294  <available_sizes>
1295    <available_sizes>assets/images/resized/0001/1070/11070v1-max-150x150.jpg</available_sizes>
1296    <available_sizes>assets/images/resized/0001/1070/11070v1-max-150x150.jpg</available_sizes>
1297  </available_sizes>
1298  <available_sizes>
1299    <available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
1300    <available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
1301  </available_sizes>
1302  <available_sizes>
1303    <available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
1304  </available_sizes>
1305</myRoot>", IndentXml(newDoc.InnerXml));
1306#endif
1307
1308#if !NET20
1309            XDocument newXDoc = JsonConvert.DeserializeXNode(json, "myRoot");
1310
1311            StringAssert.AreEqual(@"<myRoot>
1312  <available_sizes>
1313    <available_sizes>assets/images/resized/0001/1070/11070v1-max-150x150.jpg</available_sizes>
1314    <available_sizes>assets/images/resized/0001/1070/11070v1-max-150x150.jpg</available_sizes>
1315  </available_sizes>
1316  <available_sizes>
1317    <available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
1318    <available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
1319  </available_sizes>
1320  <available_sizes>
1321    <available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
1322  </available_sizes>
1323</myRoot>", IndentXml(newXDoc.ToString(SaveOptions.DisableFormatting)));
1324#endif
1325
1326#if !PORTABLE || NETSTANDARD1_3
1327            string newJson = JsonConvert.SerializeXmlNode(newDoc, Formatting.Indented);
1328            Console.WriteLine(newJson);
1329#endif
1330        }
1331
1332        [Test]
1333        public void RoundTripNestedArrays()
1334        {
1335            string json = @"{
1336  ""available_sizes"": [
1337    [
1338      ""assets/images/resized/0001/1070/11070v1-max-150x150.jpg"",
1339      ""assets/images/resized/0001/1070/11070v1-max-150x150.jpg""
1340    ],
1341    [
1342      ""assets/images/resized/0001/1070/11070v1-max-250x250.jpg"",
1343      ""assets/images/resized/0001/1070/11070v1-max-250x250.jpg""
1344    ],
1345    [
1346      ""assets/images/resized/0001/1070/11070v1-max-250x250.jpg""
1347    ]
1348  ]
1349}";
1350
1351#if !PORTABLE || NETSTANDARD1_3
1352            XmlDocument newDoc = JsonConvert.DeserializeXmlNode(json, "myRoot", true);
1353
1354            StringAssert.AreEqual(@"<myRoot>
1355  <available_sizes json:Array=""true"" xmlns:json=""http://james.newtonking.com/projects/json"">
1356    <available_sizes>assets/images/resized/0001/1070/11070v1-max-150x150.jpg</available_sizes>
1357    <available_sizes>assets/images/resized/0001/1070/11070v1-max-150x150.jpg</available_sizes>
1358  </available_sizes>
1359  <available_sizes json:Array=""true"" xmlns:json=""http://james.newtonking.com/projects/json"">
1360    <available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
1361    <available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
1362  </available_sizes>
1363  <available_sizes json:Array=""true"" xmlns:json=""http://james.newtonking.com/projects/json"">
1364    <available_sizes json:Array=""true"">assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
1365  </available_sizes>
1366</myRoot>", IndentXml(newDoc.InnerXml));
1367#endif
1368
1369#if !NET20
1370            XDocument newXDoc = JsonConvert.DeserializeXNode(json, "myRoot", true);
1371
1372            StringAssert.AreEqual(@"<myRoot>
1373  <available_sizes json:Array=""true"" xmlns:json=""http://james.newtonking.com/projects/json"">
1374    <available_sizes>assets/images/resized/0001/1070/11070v1-max-150x150.jpg</available_sizes>
1375    <available_sizes>assets/images/resized/0001/1070/11070v1-max-150x150.jpg</available_sizes>
1376  </available_sizes>
1377  <available_sizes json:Array=""true"" xmlns:json=""http://james.newtonking.com/projects/json"">
1378    <available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
1379    <available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
1380  </available_sizes>
1381  <available_sizes json:Array=""true"" xmlns:json=""http://james.newtonking.com/projects/json"">
1382    <available_sizes json:Array=""true"">assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
1383  </available_sizes>
1384</myRoot>", IndentXml(newXDoc.ToString(SaveOptions.DisableFormatting)));
1385#endif
1386
1387#if !PORTABLE || NETSTANDARD1_3
1388            string newJson = JsonConvert.SerializeXmlNode(newDoc, Formatting.Indented, true);
1389            StringAssert.AreEqual(json, newJson);
1390#endif
1391        }
1392
1393        [Test]
1394        public void MultipleNestedArraysToXml()
1395        {
1396            string json = @"{
1397  ""available_sizes"": [
1398    [
1399      [113, 150],
1400      ""assets/images/resized/0001/1070/11070v1-max-150x150.jpg""
1401    ],
1402    [
1403      [189, 250],
1404      ""assets/images/resized/0001/1070/11070v1-max-250x250.jpg""
1405    ],
1406    [
1407      [341, 450],
1408      ""assets/images/resized/0001/1070/11070v1-max-450x450.jpg""
1409    ]
1410  ]
1411}";
1412
1413#if !PORTABLE || NETSTANDARD1_3
1414            XmlDocument newDoc = JsonConvert.DeserializeXmlNode(json, "myRoot");
1415
1416            Assert.AreEqual(@"<myRoot><available_sizes><available_sizes><available_sizes>113</available_sizes><available_sizes>150</available_sizes></available_sizes><available_sizes>assets/images/resized/0001/1070/11070v1-max-150x150.jpg</available_sizes></available_sizes><available_sizes><available_sizes><available_sizes>189</available_sizes><available_sizes>250</available_sizes></available_sizes><available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes></available_sizes><available_sizes><available_sizes><available_sizes>341</available_sizes><available_sizes>450</available_sizes></available_sizes><available_sizes>assets/images/resized/0001/1070/11070v1-max-450x450.jpg</available_sizes></available_sizes></myRoot>", newDoc.InnerXml);
1417#endif
1418
1419#if !NET20
1420            XDocument newXDoc = JsonConvert.DeserializeXNode(json, "myRoot");
1421
1422            Assert.AreEqual(@"<myRoot><available_sizes><available_sizes><available_sizes>113</available_sizes><available_sizes>150</available_sizes></available_sizes><available_sizes>assets/images/resized/0001/1070/11070v1-max-150x150.jpg</available_sizes></available_sizes><available_sizes><available_sizes><available_sizes>189</available_sizes><available_sizes>250</available_sizes></available_sizes><available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes></available_sizes><available_sizes><available_sizes><available_sizes>341</available_sizes><available_sizes>450</available_sizes></available_sizes><available_sizes>assets/images/resized/0001/1070/11070v1-max-450x450.jpg</available_sizes></available_sizes></myRoot>", newXDoc.ToString(SaveOptions.DisableFormatting));
1423#endif
1424        }
1425
1426#if !PORTABLE || NETSTANDARD1_3
1427        [Test]
1428        public void Encoding()
1429        {
1430            XmlDocument doc = new XmlDocument

Large files files are truncated, but you can click here to view the full file