Json.NET
Code Coverage Statistics for Source File

Newtonsoft.Json.Tests\Converters\XmlNodeConverterTest.cs

Symbol Coverage: 96.10% (222 of 231)

Branch Coverage: 82.86% (29 of 35)

Cyclomatic Complexity Avg: 1.19 Max:3

Code Lines: 582


L V Source
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 !SILVERLIGHT
27
using System;
28
using Newtonsoft.Json.Tests.Serialization;
29
using NUnit.Framework;
30
using Newtonsoft.Json;
31
using System.IO;
32
using System.Xml;
33
using Newtonsoft.Json.Converters;
34
using Newtonsoft.Json.Utilities;
35
using Newtonsoft.Json.Linq;
36
#if !NET20
37
using System.Xml.Linq;
38
#endif
39

  
40
namespace Newtonsoft.Json.Tests.Converters
41
{
42
  public class XmlNodeConverterTest : TestFixtureBase
43
  {
44
    private string SerializeXmlNode(XmlNode node)
45
    {
46
 12
      string json = JsonConvert.SerializeXmlNode(node, Formatting.Indented);
47
 12
      XmlNodeReader reader = new XmlNodeReader(node);
48

  
49
#if !NET20
50
      XObject xNode;
51
 12
      if (node is XmlDocument)
52
      {
53
 12
        xNode = XDocument.Load(reader);
54
      }
55
 0
      else if (node is XmlAttribute)
56
      {
57
 0
        XmlAttribute attribute = (XmlAttribute) node;
58
 0
        xNode = new XAttribute(XName.Get(attribute.LocalName, attribute.NamespaceURI), attribute.Value);
59
      }
60
      else
61
      {
62
 0
        reader.MoveToContent();
63
 0
        xNode = XNode.ReadFrom(reader);
64
      }
65

  
66
 12
      string linqJson = JsonConvert.SerializeXNode(xNode, Formatting.Indented);
67

  
68
 12
      Assert.AreEqual(json, linqJson);
69
#endif
70

  
71
 12
      return json;
72
 12
    }
73

  
74
    private XmlNode DeserializeXmlNode(string json)
75
    {
76
 9
      return DeserializeXmlNode(json, null);
77
 9
    }
78

  
79
    private XmlNode DeserializeXmlNode(string json, string deserializeRootElementName)
80
    {
81
      JsonTextReader reader;
82

  
83
 10
      reader = new JsonTextReader(new StringReader(json));
84
 10
      reader.Read();
85
 10
      XmlNodeConverter converter = new XmlNodeConverter();
86
 10
      if (deserializeRootElementName != null)
87
 1
        converter.DeserializeRootElementName = deserializeRootElementName;
88

  
89
 10
      XmlNode node = (XmlNode)converter.ReadJson(reader, typeof (XmlDocument), null, new JsonSerializer());
90

  
91
#if !NET20
92
 10
     string xmlText = node.OuterXml;
93

  
94
 10
      reader = new JsonTextReader(new StringReader(json));
95
 10
      reader.Read();
96
 10
      XDocument d = (XDocument) converter.ReadJson(reader, typeof (XDocument), null, new JsonSerializer());
97

  
98
 10
      string linqXmlText = d.ToString(SaveOptions.DisableFormatting);
99
 10
      if (d.Declaration != null)
100
 7
        linqXmlText = d.Declaration + linqXmlText;
101

  
102
 10
      Assert.AreEqual(xmlText, linqXmlText);
103
#endif
104

  
105
 10
      return node;
106
 10
    }
107

  
108
    [Test]
109
    public void DocumentSerializeIndented()
110
    {
111
 1
      string xml = @"<?xml version=""1.0"" standalone=""no""?>
112
 1
<?xml-stylesheet href=""classic.xsl"" type=""text/xml""?>
113
 1
<span class=""vevent"">
114
 1
  <a class=""url"" href=""http://www.web2con.com/"">
115
 1
    <span class=""summary"">Web 2.0 Conference<![CDATA[my escaped text]]></span>
116
 1
    <abbr class=""dtstart"" title=""2005-10-05"">October 5</abbr>
117
 1
    <abbr class=""dtend"" title=""2005-10-08"">7</abbr>
118
 1
    <span class=""location"">Argent Hotel, San Francisco, CA</span>
119
 1
  </a>
120
 1
</span>";
121
 1
      XmlDocument doc = new XmlDocument();
122
 1
      doc.LoadXml(xml);
123

  
124
 1
      string jsonText = SerializeXmlNode(doc);
125
 1
      string expected = @"{
126
 1
  ""?xml"": {
127
 1
    ""@version"": ""1.0"",
128
 1
    ""@standalone"": ""no""
129
 1
  },
130
 1
  ""?xml-stylesheet"": ""href=\""classic.xsl\"" type=\""text/xml\"""",
131
 1
  ""span"": {
132
 1
    ""@class"": ""vevent"",
133
 1
    ""a"": {
134
 1
      ""@class"": ""url"",
135
 1
      ""@href"": ""http://www.web2con.com/"",
136
 1
      ""span"": [
137
 1
        {
138
 1
          ""@class"": ""summary"",
139
 1
          ""#text"": ""Web 2.0 Conference"",
140
 1
          ""#cdata-section"": ""my escaped text""
141
 1
        },
142
 1
        {
143
 1
          ""@class"": ""location"",
144
 1
          ""#text"": ""Argent Hotel, San Francisco, CA""
145
 1
        }
146
 1
      ],
147
 1
      ""abbr"": [
148
 1
        {
149
 1
          ""@class"": ""dtstart"",
150
 1
          ""@title"": ""2005-10-05"",
151
 1
          ""#text"": ""October 5""
152
 1
        },
153
 1
        {
154
 1
          ""@class"": ""dtend"",
155
 1
          ""@title"": ""2005-10-08"",
156
 1
          ""#text"": ""7""
157
 1
        }
158
 1
      ]
159
 1
    }
160
 1
  }
161
 1
}";
162

  
163
 1
      Assert.AreEqual(expected, jsonText);
164

  
165
 1
      Console.WriteLine("DocumentSerializeIndented");
166
 1
      Console.WriteLine(jsonText);
167
 1
      Console.WriteLine();
168
 1
    }
169

  
170
    [Test]
171
    public void SerializeNodeTypes()
172
    {
173
 1
      XmlDocument doc = new XmlDocument();
174
      string jsonText;
175

  
176
 1
      Console.WriteLine("SerializeNodeTypes");
177

  
178
 1
      string xml = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
179
 1
<xs:schema xs:id=""SomeID"" 
180
 1
	xmlns="""" 
181
 1
	xmlns:xs=""http://www.w3.org/2001/XMLSchema"" 
182
 1
	xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
183
 1
	<xs:element name=""MyDataSet"" msdata:IsDataSet=""true"">
184
 1
	</xs:element>
185
 1
</xs:schema>";
186

  
187
 1
      XmlDocument document = new XmlDocument();
188
 1
      document.LoadXml(xml);
189

  
190
      // XmlAttribute
191
 1
      XmlAttribute attribute = document.DocumentElement.ChildNodes[0].Attributes["IsDataSet", "urn:schemas-microsoft-com:xml-msdata"];
192
 1
      attribute.Value = "true";
193

  
194
 1
      jsonText = JsonConvert.SerializeXmlNode(attribute);
195

  
196
 1
      Console.WriteLine(jsonText);
197
 1
      Assert.AreEqual(@"{""@msdata:IsDataSet"":""true""}", jsonText);
198

  
199
#if !NET20
200
 1
      XDocument d = XDocument.Parse(xml);
201
 1
      XAttribute a = d.Root.Element("{http://www.w3.org/2001/XMLSchema}element").Attribute("{urn:schemas-microsoft-com:xml-msdata}IsDataSet");
202

  
203
 1
      jsonText = JsonConvert.SerializeXNode(a);
204

  
205
 1
      Assert.AreEqual(@"{""@msdata:IsDataSet"":""true""}", jsonText);
206
#endif
207

  
208
      // XmlProcessingInstruction
209
 1
      XmlProcessingInstruction instruction = doc.CreateProcessingInstruction("xml-stylesheet", @"href=""classic.xsl"" type=""text/xml""");
210

  
211
 1
      jsonText = JsonConvert.SerializeXmlNode(instruction);
212

  
213
 1
      Console.WriteLine(jsonText);
214
 1
      Assert.AreEqual(@"{""?xml-stylesheet"":""href=\""classic.xsl\"" type=\""text/xml\""""}", jsonText);
215

  
216

  
217
      // XmlProcessingInstruction
218
 1
      XmlCDataSection cDataSection = doc.CreateCDataSection("<Kiwi>true</Kiwi>");
219

  
220
 1
      jsonText = JsonConvert.SerializeXmlNode(cDataSection);
221

  
222
 1
      Console.WriteLine(jsonText);
223
 1
      Assert.AreEqual(@"{""#cdata-section"":""<Kiwi>true</Kiwi>""}", jsonText);
224

  
225

  
226
      // XmlElement
227
 1
      XmlElement element = doc.CreateElement("xs", "Choice", "http://www.w3.org/2001/XMLSchema");
228
 1
      element.SetAttributeNode(doc.CreateAttribute("msdata", "IsDataSet", "urn:schemas-microsoft-com:xml-msdata"));
229

  
230
 1
      XmlAttribute aa = doc.CreateAttribute(@"xmlns", "xs", "http://www.w3.org/2000/xmlns/");
231
 1
      aa.Value = "http://www.w3.org/2001/XMLSchema";
232
 1
      element.SetAttributeNode(aa);
233

  
234
 1
      aa = doc.CreateAttribute(@"xmlns", "msdata", "http://www.w3.org/2000/xmlns/");
235
 1
      aa.Value = "urn:schemas-microsoft-com:xml-msdata";
236
 1
      element.SetAttributeNode(aa);
237

  
238
 1
      element.AppendChild(instruction);
239
 1
      element.AppendChild(cDataSection);
240

  
241
 1
      doc.AppendChild(element);
242

  
243
 1
      jsonText = JsonConvert.SerializeXmlNode(element, Formatting.Indented);
244

  
245
 1
      Assert.AreEqual(@"{
246
 1
  ""xs:Choice"": {
247
 1
    ""@msdata:IsDataSet"": """",
248
 1
    ""@xmlns:xs"": ""http://www.w3.org/2001/XMLSchema"",
249
 1
    ""@xmlns:msdata"": ""urn:schemas-microsoft-com:xml-msdata"",
250
 1
    ""?xml-stylesheet"": ""href=\""classic.xsl\"" type=\""text/xml\"""",
251
 1
    ""#cdata-section"": ""<Kiwi>true</Kiwi>""
252
 1
  }
253
 1
}", jsonText);
254
 1
    }
255

  
256
    [Test]
257
    public void DocumentFragmentSerialize()
258
    {
259
 1
      XmlDocument doc = new XmlDocument();
260

  
261
 1
      XmlDocumentFragment fragement = doc.CreateDocumentFragment();
262

  
263
 1
      fragement.InnerXml = "<Item>widget</Item><Item>widget</Item>";
264

  
265
 1
      string jsonText = JsonConvert.SerializeXmlNode(fragement);
266

  
267
 1
      string expected = @"{""Item"":[""widget"",""widget""]}";
268

  
269
 1
      Assert.AreEqual(expected, jsonText);
270

  
271
 1
      Console.WriteLine("DocumentFragmentSerialize");
272
 1
      Console.WriteLine(jsonText);
273
 1
      Console.WriteLine();
274
 1
    }
275

  
276
    [Test]
277
    public void NamespaceSerializeDeserialize()
278
    {
279
 1
      string xml = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
280
 1
<xs:schema xs:id=""SomeID"" 
281
 1
	xmlns="""" 
282
 1
	xmlns:xs=""http://www.w3.org/2001/XMLSchema"" 
283
 1
	xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
284
 1
	<xs:element name=""MyDataSet"" msdata:IsDataSet=""true"">
285
 1
		<xs:complexType>
286
 1
			<xs:choice maxOccurs=""unbounded"">
287
 1
				<xs:element name=""customers"" >
288
 1
					<xs:complexType >
289
 1
						<xs:sequence>
290
 1
							<xs:element name=""CustomerID"" type=""xs:integer"" 
291
 1
										 minOccurs=""0"" />
292
 1
							<xs:element name=""CompanyName"" type=""xs:string"" 
293
 1
										 minOccurs=""0"" />
294
 1
							<xs:element name=""Phone"" type=""xs:string"" />
295
 1
						</xs:sequence>
296
 1
					</xs:complexType>
297
 1
				</xs:element>
298
 1
			</xs:choice>
299
 1
		</xs:complexType>
300
 1
	</xs:element>
301
 1
</xs:schema>";
302

  
303
 1
      XmlDocument doc = new XmlDocument();
304
 1
      doc.LoadXml(xml);
305

  
306
 1
      string jsonText = SerializeXmlNode(doc);
307

  
308
 1
      string expected = @"{
309
 1
  ""?xml"": {
310
 1
    ""@version"": ""1.0"",
311
 1
    ""@encoding"": ""utf-8""
312
 1
  },
313
 1
  ""xs:schema"": {
314
 1
    ""@xs:id"": ""SomeID"",
315
 1
    ""@xmlns"": """",
316
 1
    ""@xmlns:xs"": ""http://www.w3.org/2001/XMLSchema"",
317
 1
    ""@xmlns:msdata"": ""urn:schemas-microsoft-com:xml-msdata"",
318
 1
    ""xs:element"": {
319
 1
      ""@name"": ""MyDataSet"",
320
 1
      ""@msdata:IsDataSet"": ""true"",
321
 1
      ""xs:complexType"": {
322
 1
        ""xs:choice"": {
323
 1
          ""@maxOccurs"": ""unbounded"",
324
 1
          ""xs:element"": {
325
 1
            ""@name"": ""customers"",
326
 1
            ""xs:complexType"": {
327
 1
              ""xs:sequence"": {
328
 1
                ""xs:element"": [
329
 1
                  {
330
 1
                    ""@name"": ""CustomerID"",
331
 1
                    ""@type"": ""xs:integer"",
332
 1
                    ""@minOccurs"": ""0""
333
 1
                  },
334
 1
                  {
335
 1
                    ""@name"": ""CompanyName"",
336
 1
                    ""@type"": ""xs:string"",
337
 1
                    ""@minOccurs"": ""0""
338
 1
                  },
339
 1
                  {
340
 1
                    ""@name"": ""Phone"",
341
 1
                    ""@type"": ""xs:string""
342
 1
                  }
343
 1
                ]
344
 1
              }
345
 1
            }
346
 1
          }
347
 1
        }
348
 1
      }
349
 1
    }
350
 1
  }
351
 1
}";
352

  
353
 1
      Assert.AreEqual(expected, jsonText);
354

  
355
 1
      XmlDocument deserializedDoc = (XmlDocument)DeserializeXmlNode(jsonText);
356

  
357
 1
      Assert.AreEqual(doc.InnerXml, deserializedDoc.InnerXml);
358

  
359
 1
      Console.WriteLine("NamespaceSerializeDeserialize");
360
 1
      Console.WriteLine(jsonText);
361
 1
      Console.WriteLine(deserializedDoc.InnerXml);
362
 1
      Console.WriteLine();
363
 1
    }
364

  
365
    [Test]
366
    public void DocumentDeserialize()
367
    {
368
 1
      string jsonText = @"{
369
 1
  ""?xml"": {
370
 1
    ""@version"": ""1.0"",
371
 1
    ""@standalone"": ""no""
372
 1
  },
373
 1
  ""span"": {
374
 1
    ""@class"": ""vevent"",
375
 1
    ""a"": {
376
 1
      ""@class"": ""url"",
377
 1
      ""@href"": ""http://www.web2con.com/"",
378
 1
      ""span"": {
379
 1
        ""@class"": ""summary"",
380
 1
        ""#text"": ""Web 2.0 Conference"",
381
 1
        ""#cdata-section"": ""my escaped text""
382
 1
      }
383
 1
    }
384
 1
  }
385
 1
}";
386

  
387
 1
      XmlDocument doc = (XmlDocument)DeserializeXmlNode(jsonText);
388

  
389
 1
      string expected = @"<?xml version=""1.0"" standalone=""no""?>
390
 1
<span class=""vevent"">
391
 1
  <a class=""url"" href=""http://www.web2con.com/"">
392
 1
    <span class=""summary"">Web 2.0 Conference<![CDATA[my escaped text]]></span>
393
 1
  </a>
394
 1
</span>";
395

  
396
 1
      string formattedXml = GetIndentedInnerXml(doc);
397

  
398
 1
      Console.WriteLine("DocumentDeserialize");
399
 1
      Console.WriteLine(formattedXml);
400
 1
      Console.WriteLine();
401

  
402
 1
      Assert.AreEqual(expected, formattedXml);
403
 1
    }
404

  
405
    private string GetIndentedInnerXml(XmlNode node)
406
    {
407
 2
      XmlWriterSettings settings = new XmlWriterSettings();
408
 2
      settings.Indent = true;
409

  
410
 2
      StringWriter sw = new StringWriter();
411

  
412
 2
      using (XmlWriter writer = XmlWriter.Create(sw, settings))
413
      {
414
 2
        node.WriteTo(writer);
415
      }
416

  
417
 2
      return sw.ToString();
418
 2
    }
419

  
420
    [Test]
421
    public void SingleTextNode()
422
    {
423
 1
      string xml = @"<?xml version=""1.0"" standalone=""no""?>
424
 1
			<root>
425
 1
			  <person id=""1"">
426
 1
				<name>Alan</name>
427
 1
				<url>http://www.google.com</url>
428
 1
			  </person>
429
 1
			  <person id=""2"">
430
 1
				<name>Louis</name>
431
 1
				<url>http://www.yahoo.com</url>
432
 1
			  </person>
433
 1
			</root>";
434

  
435
 1
      XmlDocument doc = new XmlDocument();
436
 1
      doc.LoadXml(xml);
437

  
438
 1
      string jsonText = SerializeXmlNode(doc);
439

  
440
 1
      XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText);
441

  
442
 1
      Assert.AreEqual(doc.InnerXml, newDoc.InnerXml);
443
 1
    }
444

  
445
    [Test]
446
    public void EmptyNode()
447
    {
448
 1
      string xml = @"<?xml version=""1.0"" standalone=""no""?>
449
 1
			<root>
450
 1
			  <person id=""1"">
451
 1
				<name>Alan</name>
452
 1
				<url />
453
 1
			  </person>
454
 1
			  <person id=""2"">
455
 1
				<name>Louis</name>
456
 1
				<url>http://www.yahoo.com</url>
457
 1
			  </person>
458
 1
			</root>";
459

  
460
 1
      XmlDocument doc = new XmlDocument();
461
 1
      doc.LoadXml(xml);
462

  
463
 1
      string jsonText = SerializeXmlNode(doc);
464

  
465
 1
      Console.WriteLine(jsonText);
466

  
467
 1
      XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText);
468

  
469
 1
      Assert.AreEqual(doc.InnerXml, newDoc.InnerXml);
470
 1
    }
471

  
472
    [Test]
473
    public void OtherElementDataTypes()
474
    {
475
 1
      string jsonText = @"{""?xml"":{""@version"":""1.0"",""@standalone"":""no""},""root"":{""person"":[{""@id"":""1"",""Float"":2.5,""Integer"":99},{""@id"":""2"",""Boolean"":true,""date"":""\/Date(954374400000)\/""}]}}";
476

  
477
 1
      XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText);
478

  
479
 1
      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>";
480

  
481
 1
      Assert.AreEqual(expected, newDoc.InnerXml);
482
 1
    }
483

  
484
    [Test]
485
    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "XmlNodeConverter can only convert JSON that begins with an object.")]
486
    public void NoRootObject()
487
    {
488
 1
      XmlDocument newDoc = (XmlDocument)JsonConvert.DeserializeXmlNode(@"[1]");
489
 0
    }
490

  
491
    [Test]
492
    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "JSON root object has multiple properties. The root object must have a single property in order to create a valid XML document. Consider specifing a DeserializeRootElementName.")]
493
    public void RootObjectMultipleProperties()
494
    {
495
 1
      XmlDocument newDoc = (XmlDocument)JsonConvert.DeserializeXmlNode(@"{Prop1:1,Prop2:2}");
496
 0
    }
497

  
498
    [Test]
499
    public void JavaScriptConstructor()
500
    {
501
 1
      string jsonText = @"{root:{r:new Date(34343, 55)}}";
502

  
503
 1
      XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText);
504

  
505
 1
      string expected = @"<root><r><Date>34343</Date><Date>55</Date></r></root>";
506

  
507
 1
      Assert.AreEqual(expected, newDoc.InnerXml);
508

  
509
 1
      string json = SerializeXmlNode(newDoc);
510
 1
      expected = @"{
511
 1
  ""root"": {
512
 1
    ""r"": {
513
 1
      ""Date"": [
514
 1
        ""34343"",
515
 1
        ""55""
516
 1
      ]
517
 1
    }
518
 1
  }
519
 1
}";
520

  
521
 1
      Assert.AreEqual(expected, json);
522
 1
    }
523

  
524
    [Test]
525
    public void ForceJsonArray()
526
    {
527
 1
      string arrayXml = @"<root xmlns:json=""http://james.newtonking.com/projects/json"">
528
 1
			  <person id=""1"">
529
 1
				  <name>Alan</name>
530
 1
				  <url>http://www.google.com</url>
531
 1
				  <role json:Array=""true"">Admin</role>
532
 1
			  </person>
533
 1
			</root>";
534

  
535
 1
      XmlDocument arrayDoc = new XmlDocument();
536
 1
      arrayDoc.LoadXml(arrayXml);
537

  
538
 1
      string arrayJsonText = SerializeXmlNode(arrayDoc);
539
 1
      string expected = @"{
540
 1
  ""root"": {
541
 1
    ""person"": {
542
 1
      ""@id"": ""1"",
543
 1
      ""name"": ""Alan"",
544
 1
      ""url"": ""http://www.google.com"",
545
 1
      ""role"": [
546
 1
        ""Admin""
547
 1
      ]
548
 1
    }
549
 1
  }
550
 1
}";
551
 1
      Assert.AreEqual(expected, arrayJsonText);
552

  
553
 1
      arrayXml = @"<root xmlns:json=""http://james.newtonking.com/projects/json"">
554
 1
			  <person id=""1"">
555
 1
				  <name>Alan</name>
556
 1
				  <url>http://www.google.com</url>
557
 1
				  <role json:Array=""true"">Admin1</role>
558
 1
				  <role json:Array=""true"">Admin2</role>
559
 1
			  </person>
560
 1
			</root>";
561

  
562
 1
      arrayDoc = new XmlDocument();
563
 1
      arrayDoc.LoadXml(arrayXml);
564

  
565
 1
      arrayJsonText = SerializeXmlNode(arrayDoc);
566
 1
      expected = @"{
567
 1
  ""root"": {
568
 1
    ""person"": {
569
 1
      ""@id"": ""1"",
570
 1
      ""name"": ""Alan"",
571
 1
      ""url"": ""http://www.google.com"",
572
 1
      ""role"": [
573
 1
        ""Admin1"",
574
 1
        ""Admin2""
575
 1
      ]
576
 1
    }
577
 1
  }
578
 1
}";
579
 1
      Assert.AreEqual(expected, arrayJsonText);
580

  
581
 1
      arrayXml = @"<root xmlns:json=""http://james.newtonking.com/projects/json"">
582
 1
			  <person id=""1"">
583
 1
				  <name>Alan</name>
584
 1
				  <url>http://www.google.com</url>
585
 1
				  <role json:Array=""false"">Admin1</role>
586
 1
			  </person>
587
 1
			</root>";
588

  
589
 1
      arrayDoc = new XmlDocument();
590
 1
      arrayDoc.LoadXml(arrayXml);
591

  
592
 1
      arrayJsonText = SerializeXmlNode(arrayDoc);
593
 1
      expected = @"{
594
 1
  ""root"": {
595
 1
    ""person"": {
596
 1
      ""@id"": ""1"",
597
 1
      ""name"": ""Alan"",
598
 1
      ""url"": ""http://www.google.com"",
599
 1
      ""role"": ""Admin1""
600
 1
    }
601
 1
  }
602
 1
}";
603
 1
      Assert.AreEqual(expected, arrayJsonText);
604
 1
    }
605

  
606
    [Test]
607
    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "JSON root object has multiple properties. The root object must have a single property in order to create a valid XML document. Consider specifing a DeserializeRootElementName.")]
608
    public void MultipleRootPropertiesXmlDocument()
609
    {
610
 1
      string json = @"{""count"": 773840,""photos"": null}";
611

  
612
 1
      JsonConvert.DeserializeXmlNode(json);
613
 0
    }
614

  
615
#if !NET20
616
    [Test]
617
    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "JSON root object has multiple properties. The root object must have a single property in order to create a valid XML document. Consider specifing a DeserializeRootElementName.")]
618
    public void MultipleRootPropertiesXDocument()
619
    {
620
 1
      string json = @"{""count"": 773840,""photos"": null}";
621

  
622
 1
      JsonConvert.DeserializeXNode(json);
623
 0
    }
624
#endif
625

  
626
    [Test]
627
    public void MultipleRootPropertiesAddRootElement()
628
    {
629
 1
      string json = @"{""count"": 773840,""photos"": 773840}";
630

  
631
 1
      XmlDocument newDoc = JsonConvert.DeserializeXmlNode(json, "myRoot");
632

  
633
 1
      Assert.AreEqual(@"<myRoot><count>773840</count><photos>773840</photos></myRoot>", newDoc.InnerXml);
634

  
635
#if !NET20
636
 1
     XDocument newXDoc = JsonConvert.DeserializeXNode(json, "myRoot");
637

  
638
 1
      Assert.AreEqual(@"<myRoot><count>773840</count><photos>773840</photos></myRoot>", newXDoc.ToString(SaveOptions.DisableFormatting));
639
#endif
640
 1
    }
641

  
642
    [Test]
643
    public void NestedArrays()
644
    {
645
 1
      string json = @"{
646
 1
  ""available_sizes"": [
647
 1
    [
648
 1
      ""assets/images/resized/0001/1070/11070v1-max-150x150.jpg"",
649
 1
      ""assets/images/resized/0001/1070/11070v1-max-150x150.jpg""
650
 1
    ],
651
 1
    [
652
 1
      ""assets/images/resized/0001/1070/11070v1-max-250x250.jpg"",
653
 1
      ""assets/images/resized/0001/1070/11070v1-max-250x250.jpg""
654
 1
    ]
655
 1
  ]
656
 1
}";
657

  
658
 1
      XmlDocument newDoc = JsonConvert.DeserializeXmlNode(json, "myRoot");
659

  
660
 1
      Assert.AreEqual(@"<myRoot><available_sizes><available_sizes>assets/images/resized/0001/1070/11070v1-max-150x150.jpg</available_sizes><available_sizes>assets/images/resized/0001/1070/11070v1-max-150x150.jpg</available_sizes></available_sizes><available_sizes><available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes><available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes></available_sizes></myRoot>", newDoc.InnerXml);
661

  
662
#if !NET20
663
 1
      XDocument newXDoc = JsonConvert.DeserializeXNode(json, "myRoot");
664

  
665
 1
      Assert.AreEqual(@"<myRoot><available_sizes><available_sizes>assets/images/resized/0001/1070/11070v1-max-150x150.jpg</available_sizes><available_sizes>assets/images/resized/0001/1070/11070v1-max-150x150.jpg</available_sizes></available_sizes><available_sizes><available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes><available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes></available_sizes></myRoot>", newXDoc.ToString(SaveOptions.DisableFormatting));
666
#endif
667
 1
    }
668

  
669
    [Test]
670
    public void MultipleNestedArraysToXml()
671
    {
672
 1
      string json = @"{
673
 1
  ""available_sizes"": [
674
 1
    [
675
 1
      [113, 150],
676
 1
      ""assets/images/resized/0001/1070/11070v1-max-150x150.jpg""
677
 1
    ],
678
 1
    [
679
 1
      [189, 250],
680
 1
      ""assets/images/resized/0001/1070/11070v1-max-250x250.jpg""
681
 1
    ],
682
 1
    [
683
 1
      [341, 450],
684
 1
      ""assets/images/resized/0001/1070/11070v1-max-450x450.jpg""
685
 1
    ]
686
 1
  ]
687
 1
}";
688

  
689
 1
      XmlDocument newDoc = JsonConvert.DeserializeXmlNode(json, "myRoot");
690

  
691
 1
      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);
692

  
693
#if !NET20
694
 1
      XDocument newXDoc = JsonConvert.DeserializeXNode(json, "myRoot");
695

  
696
 1
      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));
697
#endif
698
 1
    }
699

  
700
    [Test]
701
    public void Encoding()
702
    {
703
 1
      XmlDocument doc = new XmlDocument();
704

  
705
 1
      doc.LoadXml(@"<name>O""Connor</name>"); // i use "" so it will be easier to see the  problem
706

  
707
 1
      string json = SerializeXmlNode(doc);
708
 1
      Assert.AreEqual(@"{
709
 1
  ""name"": ""O\""Connor""
710
 1
}", json);
711
 1
    }
712

  
713
    [Test]
714
    public void SerializeComment()
715
    {
716
 1
      string xml = @"<span class=""vevent"">
717
 1
  <a class=""url"" href=""http://www.web2con.com/"">Text</a><!-- Hi! -->
718
 1
</span>";
719
 1
      XmlDocument doc = new XmlDocument();
720
 1
      doc.LoadXml(xml);
721

  
722
 1
      string jsonText = SerializeXmlNode(doc);
723

  
724
 1
      string expected = @"{
725
 1
  ""span"": {
726
 1
    ""@class"": ""vevent"",
727
 1
    ""a"": {
728
 1
      ""@class"": ""url"",
729
 1
      ""@href"": ""http://www.web2con.com/"",
730
 1
      ""#text"": ""Text""
731
 1
    }/* Hi! */
732
 1
  }
733
 1
}";
734

  
735
 1
      Assert.AreEqual(expected, jsonText);
736

  
737
 1
      XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText);
738
 1
      Assert.AreEqual(@"<span class=""vevent""><a class=""url"" href=""http://www.web2con.com/"">Text</a><!-- Hi! --></span>", newDoc.InnerXml);
739
 1
    }
740

  
741
    [Test]
742
    public void SerializeExample()
743
    {
744
 1
      string xml = @"<?xml version=""1.0"" standalone=""no""?>
745
 1
			<root>
746
 1
			  <person id=""1"">
747
 1
				<name>Alan</name>
748
 1
				<url>http://www.google.com</url>
749
 1
			  </person>
750
 1
			  <person id=""2"">
751
 1
				<name>Louis</name>
752
 1
				<url>http://www.yahoo.com</url>
753
 1
			  </person>
754
 1
			</root>";
755

  
756
 1
      XmlDocument doc = new XmlDocument();
757
 1
      doc.LoadXml(xml);
758

  
759
 1
      string jsonText = SerializeXmlNode(doc);
760
      // {
761
      //   "?xml": {
762
      //     "@version": "1.0",
763
      //     "@standalone": "no"
764
      //   },
765
      //   "root": {
766
      //     "person": [
767
      //       {
768
      //         "@id": "1",
769
      //         "name": "Alan",
770
      //         "url": "http://www.google.com"
771
      //       },
772
      //       {
773
      //         "@id": "2",
774
      //         "name": "Louis",
775
      //         "url": "http://www.yahoo.com"
776
      //       }
777
      //     ]
778
      //   }
779
      // }
780

  
781
      // format
782
 1
      jsonText = JObject.Parse(jsonText).ToString();
783

  
784
 1
      Assert.AreEqual(@"{
785
 1
  ""?xml"": {
786
 1
    ""@version"": ""1.0"",
787
 1
    ""@standalone"": ""no""
788
 1
  },
789
 1
  ""root"": {
790
 1
    ""person"": [
791
 1
      {
792
 1
        ""@id"": ""1"",
793
 1
        ""name"": ""Alan"",
794
 1
        ""url"": ""http://www.google.com""
795
 1
      },
796
 1
      {
797
 1
        ""@id"": ""2"",
798
 1
        ""name"": ""Louis"",
799
 1
        ""url"": ""http://www.yahoo.com""
800
 1
      }
801
 1
    ]
802
 1
  }
803
 1
}", jsonText);
804

  
805
 1
      XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText);
806

  
807
 1
      Assert.AreEqual(doc.InnerXml, newDoc.InnerXml);
808
 1
    }
809

  
810
    [Test]
811
    public void DeserializeExample()
812
    {
813
 1
      string json = @"{
814
 1
        ""?xml"": {
815
 1
          ""@version"": ""1.0"",
816
 1
          ""@standalone"": ""no""
817
 1
        },
818
 1
        ""root"": {
819
 1
          ""person"": [
820
 1
            {
821
 1
              ""@id"": ""1"",
822
 1
              ""name"": ""Alan"",
823
 1
              ""url"": ""http://www.google.com""
824
 1
            },
825
 1
            {
826
 1
              ""@id"": ""2"",
827
 1
              ""name"": ""Louis"",
828
 1
              ""url"": ""http://www.yahoo.com""
829
 1
            }
830
 1
          ]
831
 1
        }
832
 1
      }";
833

  
834
 1
      XmlDocument doc = (XmlDocument)DeserializeXmlNode(json);
835
      // <?xml version="1.0" standalone="no"?>
836
      // <root>
837
      //   <person id="1">
838
      //   <name>Alan</name>
839
      //   <url>http://www.google.com</url>
840
      //   </person>
841
      //   <person id="2">
842
      //   <name>Louis</name>
843
      //   <url>http://www.yahoo.com</url>
844
      //   </person>
845
      // </root>
846

  
847
 1
      Assert.AreEqual(@"<?xml version=""1.0"" standalone=""no""?>
848
 1
<root>
849
 1
<person id=""1"">
850
 1
<name>Alan</name>
851
 1
<url>http://www.google.com</url>
852
 1
</person>
853
 1
<person id=""2"">
854
 1
<name>Louis</name>
855
 1
<url>http://www.yahoo.com</url>
856
 1
</person>
857
 1
</root>".Replace(Environment.NewLine, string.Empty), doc.InnerXml);
858
 1
    }
859

  
860
    [Test]
861
    public void SerializeDeserializeSpecialProperties()
862
    {
863
 1
      PreserveReferencesHandlingTests.CircularDictionary circularDictionary = new PreserveReferencesHandlingTests.CircularDictionary();
864
 1
      circularDictionary.Add("other", new PreserveReferencesHandlingTests.CircularDictionary { { "blah", null } });
865
 1
      circularDictionary.Add("self", circularDictionary);
866

  
867
 1
      string json = JsonConvert.SerializeObject(circularDictionary, Formatting.Indented,
868
 1
        new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.All });
869

  
870
 1
      Assert.AreEqual(@"{
871
 1
  ""$id"": ""1"",
872
 1
  ""other"": {
873
 1
    ""$id"": ""2"",
874
 1
    ""blah"": null
875
 1
  },
876
 1
  ""self"": {
877
 1
    ""$ref"": ""1""
878
 1
  }
879
 1
}", json);
880

  
881
 1
      XmlNode node = DeserializeXmlNode(json, "root");
882
 1
      string xml = GetIndentedInnerXml(node);
883
 1
      string expected = @"<?xml version=""1.0"" encoding=""utf-16""?>
884
 1
<root xmlns:json=""http://james.newtonking.com/projects/json"" json:id=""1"">
885
 1
  <other json:id=""2"">
886
 1
    <blah />
887
 1
  </other>
888
 1
  <self json:ref=""1"" />
889
 1
</root>";
890

  
891
 1
      Assert.AreEqual(expected, xml);
892

  
893
 1
      string xmlJson = SerializeXmlNode(node);
894
 1
      string expectedXmlJson = @"{
895
 1
  ""root"": {
896
 1
    ""$id"": ""1"",
897
 1
    ""other"": {
898
 1
      ""$id"": ""2"",
899
 1
      ""blah"": null
900
 1
    },
901
 1
    ""self"": {
902
 1
      ""$ref"": ""1""
903
 1
    }
904
 1
  }
905
 1
}";
906

  
907
 1
      Assert.AreEqual(expectedXmlJson, xmlJson);
908
 1
    }
909
  }
910
}
911
#endif