PageRenderTime 35ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 1ms

/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs

https://bitbucket.org/Ecarestia/newtonsoft.json
C# | 2987 lines | 2531 code | 399 blank | 57 comment | 16 complexity | 10293e1b597b93bcf08d97affd061578 MD5 | raw 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. using System.Globalization;
  26. #if NET20
  27. using Newtonsoft.Json.Utilities.LinqBridge;
  28. #else
  29. using System.Linq;
  30. #endif
  31. using System.Text;
  32. #if !(DNXCORE50 || PORTABLE40)
  33. using System;
  34. using System.Collections.Generic;
  35. using Newtonsoft.Json.Tests.Serialization;
  36. using Newtonsoft.Json.Tests.TestObjects;
  37. #if DNXCORE50
  38. using Xunit;
  39. using Test = Xunit.FactAttribute;
  40. using Assert = Newtonsoft.Json.Tests.XUnitAssert;
  41. #else
  42. using NUnit.Framework;
  43. #endif
  44. using Newtonsoft.Json;
  45. using System.IO;
  46. using System.Xml;
  47. using Newtonsoft.Json.Converters;
  48. using Newtonsoft.Json.Utilities;
  49. using Newtonsoft.Json.Linq;
  50. #if !NET20
  51. using System.Xml.Linq;
  52. #endif
  53. namespace Newtonsoft.Json.Tests.Converters
  54. {
  55. [TestFixture]
  56. public class XmlNodeConverterTest : TestFixtureBase
  57. {
  58. #if !PORTABLE
  59. private string SerializeXmlNode(XmlNode node)
  60. {
  61. string json = JsonConvert.SerializeXmlNode(node, Formatting.Indented);
  62. XmlNodeReader reader = new XmlNodeReader(node);
  63. #if !NET20
  64. XObject xNode;
  65. if (node is XmlDocument)
  66. {
  67. xNode = XDocument.Load(reader);
  68. }
  69. else if (node is XmlAttribute)
  70. {
  71. XmlAttribute attribute = (XmlAttribute)node;
  72. xNode = new XAttribute(XName.Get(attribute.LocalName, attribute.NamespaceURI), attribute.Value);
  73. }
  74. else
  75. {
  76. reader.MoveToContent();
  77. xNode = XNode.ReadFrom(reader);
  78. }
  79. string linqJson = JsonConvert.SerializeXNode(xNode, Formatting.Indented);
  80. Assert.AreEqual(json, linqJson);
  81. #endif
  82. return json;
  83. }
  84. private XmlNode DeserializeXmlNode(string json)
  85. {
  86. return DeserializeXmlNode(json, null);
  87. }
  88. private XmlNode DeserializeXmlNode(string json, string deserializeRootElementName)
  89. {
  90. JsonTextReader reader;
  91. reader = new JsonTextReader(new StringReader(json));
  92. reader.Read();
  93. XmlNodeConverter converter = new XmlNodeConverter();
  94. if (deserializeRootElementName != null)
  95. {
  96. converter.DeserializeRootElementName = deserializeRootElementName;
  97. }
  98. XmlNode node = (XmlNode)converter.ReadJson(reader, typeof(XmlDocument), null, new JsonSerializer());
  99. #if !NET20
  100. string xmlText = node.OuterXml;
  101. reader = new JsonTextReader(new StringReader(json));
  102. reader.Read();
  103. XDocument d = (XDocument)converter.ReadJson(reader, typeof(XDocument), null, new JsonSerializer());
  104. string linqXmlText = d.ToString(SaveOptions.DisableFormatting);
  105. if (d.Declaration != null)
  106. {
  107. linqXmlText = d.Declaration + linqXmlText;
  108. }
  109. Assert.AreEqual(xmlText, linqXmlText);
  110. #endif
  111. return node;
  112. }
  113. #endif
  114. private string IndentXml(string xml)
  115. {
  116. XmlReader reader = XmlReader.Create(new StringReader(xml));
  117. StringWriter sw = new StringWriter();
  118. XmlWriter writer = XmlWriter.Create(sw, new XmlWriterSettings { Indent = true, OmitXmlDeclaration = true });
  119. while (reader.Read())
  120. {
  121. writer.WriteNode(reader, false);
  122. }
  123. writer.Flush();
  124. return sw.ToString();
  125. }
  126. #if !NET20
  127. [Test]
  128. public void SerializeDollarProperty()
  129. {
  130. string json1 = @"{""$"":""test""}";
  131. var doc = JsonConvert.DeserializeXNode(json1);
  132. Assert.AreEqual(@"<_x0024_>test</_x0024_>", doc.ToString());
  133. var json2 = JsonConvert.SerializeXNode(doc);
  134. Assert.AreEqual(json1, json2);
  135. }
  136. [Test]
  137. public void SerializeNonKnownDollarProperty()
  138. {
  139. string json1 = @"{""$JELLY"":""test""}";
  140. var doc = JsonConvert.DeserializeXNode(json1);
  141. Console.WriteLine(doc.ToString());
  142. Assert.AreEqual(@"<_x0024_JELLY>test</_x0024_JELLY>", doc.ToString());
  143. var json2 = JsonConvert.SerializeXNode(doc);
  144. Assert.AreEqual(json1, json2);
  145. }
  146. public class MyModel
  147. {
  148. public string MyProperty { get; set; }
  149. }
  150. [Test]
  151. public void ConvertNullString()
  152. {
  153. JObject json = new JObject();
  154. json["Prop1"] = (string)null;
  155. json["Prop2"] = new MyModel().MyProperty;
  156. var xmlNodeConverter = new XmlNodeConverter { DeserializeRootElementName = "object" };
  157. var jsonSerializerSettings = new JsonSerializerSettings { Converters = new JsonConverter[] { xmlNodeConverter } };
  158. var jsonSerializer = JsonSerializer.CreateDefault(jsonSerializerSettings);
  159. XDocument d = json.ToObject<XDocument>(jsonSerializer);
  160. StringAssert.Equals(@"<object>
  161. <Prop1 />
  162. <Prop2 />
  163. </object>", d.ToString());
  164. }
  165. public class Foo
  166. {
  167. public XElement Bar { get; set; }
  168. }
  169. [Test]
  170. public void SerializeAndDeserializeXElement()
  171. {
  172. Foo foo = new Foo { Bar = null };
  173. string json = JsonConvert.SerializeObject(foo);
  174. Assert.AreEqual(@"{""Bar"":null}", json);
  175. Foo foo2 = JsonConvert.DeserializeObject<Foo>(json);
  176. Assert.IsNull(foo2.Bar);
  177. }
  178. [Test]
  179. public void MultipleNamespacesXDocument()
  180. {
  181. 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"" />";
  182. XDocument d = XDocument.Parse(xml);
  183. string json = JsonConvert.SerializeObject(d, Formatting.Indented);
  184. StringAssert.AreEqual(@"{
  185. ""result"": {
  186. ""@xp_0:end"": ""2014-08-15 13:12:11.9184"",
  187. ""@xp_0:start"": ""2014-08-15 13:11:49.3140"",
  188. ""@xp_0:time_diff"": ""22604.3836"",
  189. ""@xmlns:xp_0"": ""Test1"",
  190. ""@p2:end"": ""2014-08-15 13:13:49.5522"",
  191. ""@p2:start"": ""2014-08-15 13:13:49.0268"",
  192. ""@p2:time_diff"": ""525.4646"",
  193. ""@xmlns:p2"": ""Test2""
  194. }
  195. }", json);
  196. XDocument doc = JsonConvert.DeserializeObject<XDocument>(json);
  197. StringAssert.AreEqual(xml, doc.ToString());
  198. }
  199. #endif
  200. #if !PORTABLE
  201. [Test]
  202. public void MultipleNamespacesXmlDocument()
  203. {
  204. 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"" />";
  205. XmlDocument d = new XmlDocument();
  206. d.LoadXml(xml);
  207. string json = JsonConvert.SerializeObject(d, Formatting.Indented);
  208. StringAssert.AreEqual(@"{
  209. ""result"": {
  210. ""@xp_0:end"": ""2014-08-15 13:12:11.9184"",
  211. ""@xp_0:start"": ""2014-08-15 13:11:49.3140"",
  212. ""@xp_0:time_diff"": ""22604.3836"",
  213. ""@xmlns:xp_0"": ""Test1"",
  214. ""@p2:end"": ""2014-08-15 13:13:49.5522"",
  215. ""@p2:start"": ""2014-08-15 13:13:49.0268"",
  216. ""@p2:time_diff"": ""525.4646"",
  217. ""@xmlns:p2"": ""Test2""
  218. }
  219. }", json);
  220. XmlDocument doc = JsonConvert.DeserializeObject<XmlDocument>(json);
  221. StringAssert.AreEqual(xml, doc.OuterXml);
  222. }
  223. [Test]
  224. public void SerializeXmlElement()
  225. {
  226. string xml = @"<payload>
  227. <Country>6</Country>
  228. <FinancialTransactionApprovalRequestUID>79</FinancialTransactionApprovalRequestUID>
  229. <TransactionStatus>Approved</TransactionStatus>
  230. <StatusChangeComment></StatusChangeComment>
  231. <RequestedBy>Someone</RequestedBy>
  232. </payload>";
  233. var xmlDocument = new XmlDocument();
  234. xmlDocument.LoadXml(xml);
  235. var result = xmlDocument.FirstChild.ChildNodes.Cast<XmlNode>().ToArray();
  236. var json = JsonConvert.SerializeObject(result, Formatting.Indented); // <--- fails here with the cast message
  237. StringAssert.AreEqual(@"[
  238. {
  239. ""Country"": ""6""
  240. },
  241. {
  242. ""FinancialTransactionApprovalRequestUID"": ""79""
  243. },
  244. {
  245. ""TransactionStatus"": ""Approved""
  246. },
  247. {
  248. ""StatusChangeComment"": """"
  249. },
  250. {
  251. ""RequestedBy"": ""Someone""
  252. }
  253. ]", json);
  254. }
  255. #endif
  256. #if !NET20
  257. [Test]
  258. public void SerializeXElement()
  259. {
  260. string xml = @"<payload>
  261. <Country>6</Country>
  262. <FinancialTransactionApprovalRequestUID>79</FinancialTransactionApprovalRequestUID>
  263. <TransactionStatus>Approved</TransactionStatus>
  264. <StatusChangeComment></StatusChangeComment>
  265. <RequestedBy>Someone</RequestedBy>
  266. </payload>";
  267. var xmlDocument = XDocument.Parse(xml);
  268. var result = xmlDocument.Root.Nodes().ToArray();
  269. var json = JsonConvert.SerializeObject(result, Formatting.Indented); // <--- fails here with the cast message
  270. StringAssert.AreEqual(@"[
  271. {
  272. ""Country"": ""6""
  273. },
  274. {
  275. ""FinancialTransactionApprovalRequestUID"": ""79""
  276. },
  277. {
  278. ""TransactionStatus"": ""Approved""
  279. },
  280. {
  281. ""StatusChangeComment"": """"
  282. },
  283. {
  284. ""RequestedBy"": ""Someone""
  285. }
  286. ]", json);
  287. }
  288. public class DecimalContainer
  289. {
  290. public decimal Number { get; set; }
  291. }
  292. [Test]
  293. public void FloatParseHandlingDecimal()
  294. {
  295. decimal d = (decimal)Math.PI + 1000000000m;
  296. var x = new DecimalContainer { Number = d };
  297. var json = JsonConvert.SerializeObject(x, Formatting.Indented);
  298. XDocument doc1 = JsonConvert.DeserializeObject<XDocument>(json, new JsonSerializerSettings
  299. {
  300. Converters = { new XmlNodeConverter() },
  301. FloatParseHandling = FloatParseHandling.Decimal
  302. });
  303. var xml = doc1.ToString();
  304. Assert.AreEqual("<Number>1000000003.14159265358979</Number>", xml);
  305. string json2 = JsonConvert.SerializeObject(doc1, Formatting.Indented);
  306. DecimalContainer x2 = JsonConvert.DeserializeObject<DecimalContainer>(json2);
  307. Assert.AreEqual(x.Number, x2.Number);
  308. }
  309. public class DateTimeOffsetContainer
  310. {
  311. public DateTimeOffset Date { get; set; }
  312. }
  313. [Test]
  314. public void DateTimeParseHandlingOffset()
  315. {
  316. DateTimeOffset d = new DateTimeOffset(2012, 12, 12, 12, 44, 1, TimeSpan.FromHours(12).Add(TimeSpan.FromMinutes(34)));
  317. var x = new DateTimeOffsetContainer { Date = d };
  318. var json = JsonConvert.SerializeObject(x, Formatting.Indented);
  319. XDocument doc1 = JsonConvert.DeserializeObject<XDocument>(json, new JsonSerializerSettings
  320. {
  321. Converters = { new XmlNodeConverter() },
  322. DateParseHandling = DateParseHandling.DateTimeOffset
  323. });
  324. var xml = doc1.ToString();
  325. Assert.AreEqual("<Date>2012-12-12T12:44:01+12:34</Date>", xml);
  326. string json2 = JsonConvert.SerializeObject(doc1, Formatting.Indented);
  327. DateTimeOffsetContainer x2 = JsonConvert.DeserializeObject<DateTimeOffsetContainer>(json2);
  328. Assert.AreEqual(x.Date, x2.Date);
  329. }
  330. [Test]
  331. public void GroupElementsOfTheSameName()
  332. {
  333. string xml = "<root><p>Text1<span>Span1</span> <span>Span2</span> Text2</p></root>";
  334. string json = JsonConvert.SerializeXNode(XElement.Parse(xml));
  335. Assert.AreEqual(@"{""root"":{""p"":{""#text"":[""Text1"","" Text2""],""span"":[""Span1"",""Span2""]}}}", json);
  336. XDocument doc = JsonConvert.DeserializeXNode(json);
  337. StringAssert.AreEqual(@"<root>
  338. <p>Text1 Text2<span>Span1</span><span>Span2</span></p>
  339. </root>", doc.ToString());
  340. }
  341. #if !PORTABLE
  342. [Test]
  343. public void SerializeEmptyDocument()
  344. {
  345. XmlDocument doc = new XmlDocument();
  346. doc.LoadXml("<root />");
  347. string json = JsonConvert.SerializeXmlNode(doc, Formatting.Indented, true);
  348. Assert.AreEqual("null", json);
  349. doc = new XmlDocument();
  350. doc.LoadXml("<root></root>");
  351. json = JsonConvert.SerializeXmlNode(doc, Formatting.Indented, true);
  352. Assert.AreEqual(@"""""", json);
  353. XDocument doc1 = XDocument.Parse("<root />");
  354. json = JsonConvert.SerializeXNode(doc1, Formatting.Indented, true);
  355. Assert.AreEqual("null", json);
  356. doc1 = XDocument.Parse("<root></root>");
  357. json = JsonConvert.SerializeXNode(doc1, Formatting.Indented, true);
  358. Assert.AreEqual(@"""""", json);
  359. }
  360. #endif
  361. [Test]
  362. public void SerializeAndDeserializeXmlWithNamespaceInChildrenAndNoValueInChildren()
  363. {
  364. var xmlString = @"<root>
  365. <b xmlns='http://www.example.com/ns'/>
  366. <c>AAA</c>
  367. <test>adad</test>
  368. </root>";
  369. var xml = XElement.Parse(xmlString);
  370. var json1 = JsonConvert.SerializeXNode(xml);
  371. var xmlBack = JsonConvert.DeserializeObject<XElement>(json1);
  372. var equals = XElement.DeepEquals(xmlBack, xml);
  373. Assert.IsTrue(equals);
  374. }
  375. #if !PORTABLE
  376. [Test]
  377. public void DeserializeUndeclaredNamespacePrefix()
  378. {
  379. XmlDocument doc = JsonConvert.DeserializeXmlNode("{ A: { '@xsi:nil': true } }");
  380. Assert.AreEqual(@"<A nil=""true"" />", doc.OuterXml);
  381. XDocument xdoc = JsonConvert.DeserializeXNode("{ A: { '@xsi:nil': true } }");
  382. Assert.AreEqual(doc.OuterXml, xdoc.ToString());
  383. }
  384. #endif
  385. #endif
  386. #if !PORTABLE
  387. [Test]
  388. public void DeserializeMultipleRootElements()
  389. {
  390. string json = @"{
  391. ""Id"": 1,
  392. ""Email"": ""james@example.com"",
  393. ""Active"": true,
  394. ""CreatedDate"": ""2013-01-20T00:00:00Z"",
  395. ""Roles"": [
  396. ""User"",
  397. ""Admin""
  398. ],
  399. ""Team"": {
  400. ""Id"": 2,
  401. ""Name"": ""Software Developers"",
  402. ""Description"": ""Creators of fine software products and services.""
  403. }
  404. }";
  405. ExceptionAssert.Throws<JsonSerializationException>(
  406. () => { JsonConvert.DeserializeXmlNode(json); },
  407. "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.");
  408. }
  409. [Test]
  410. public void DocumentSerializeIndented()
  411. {
  412. string xml = @"<?xml version=""1.0"" standalone=""no""?>
  413. <?xml-stylesheet href=""classic.xsl"" type=""text/xml""?>
  414. <span class=""vevent"">
  415. <a class=""url"" href=""http://www.web2con.com/"">
  416. <span class=""summary"">Web 2.0 Conference<![CDATA[my escaped text]]></span>
  417. <abbr class=""dtstart"" title=""2005-10-05"">October 5</abbr>
  418. <abbr class=""dtend"" title=""2005-10-08"">7</abbr>
  419. <span class=""location"">Argent Hotel, San Francisco, CA</span>
  420. </a>
  421. </span>";
  422. XmlDocument doc = new XmlDocument();
  423. doc.LoadXml(xml);
  424. string jsonText = SerializeXmlNode(doc);
  425. string expected = @"{
  426. ""?xml"": {
  427. ""@version"": ""1.0"",
  428. ""@standalone"": ""no""
  429. },
  430. ""?xml-stylesheet"": ""href=\""classic.xsl\"" type=\""text/xml\"""",
  431. ""span"": {
  432. ""@class"": ""vevent"",
  433. ""a"": {
  434. ""@class"": ""url"",
  435. ""@href"": ""http://www.web2con.com/"",
  436. ""span"": [
  437. {
  438. ""@class"": ""summary"",
  439. ""#text"": ""Web 2.0 Conference"",
  440. ""#cdata-section"": ""my escaped text""
  441. },
  442. {
  443. ""@class"": ""location"",
  444. ""#text"": ""Argent Hotel, San Francisco, CA""
  445. }
  446. ],
  447. ""abbr"": [
  448. {
  449. ""@class"": ""dtstart"",
  450. ""@title"": ""2005-10-05"",
  451. ""#text"": ""October 5""
  452. },
  453. {
  454. ""@class"": ""dtend"",
  455. ""@title"": ""2005-10-08"",
  456. ""#text"": ""7""
  457. }
  458. ]
  459. }
  460. }
  461. }";
  462. StringAssert.AreEqual(expected, jsonText);
  463. }
  464. [Test]
  465. public void SerializeNodeTypes()
  466. {
  467. XmlDocument doc = new XmlDocument();
  468. string jsonText;
  469. string xml = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
  470. <xs:schema xs:id=""SomeID""
  471. xmlns=""""
  472. xmlns:xs=""http://www.w3.org/2001/XMLSchema""
  473. xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
  474. <xs:element name=""MyDataSet"" msdata:IsDataSet=""true"">
  475. </xs:element>
  476. </xs:schema>";
  477. XmlDocument document = new XmlDocument();
  478. document.LoadXml(xml);
  479. // XmlAttribute
  480. XmlAttribute attribute = document.DocumentElement.ChildNodes[0].Attributes["IsDataSet", "urn:schemas-microsoft-com:xml-msdata"];
  481. attribute.Value = "true";
  482. jsonText = JsonConvert.SerializeXmlNode(attribute);
  483. Assert.AreEqual(@"{""@msdata:IsDataSet"":""true""}", jsonText);
  484. #if !NET20
  485. XDocument d = XDocument.Parse(xml);
  486. XAttribute a = d.Root.Element("{http://www.w3.org/2001/XMLSchema}element").Attribute("{urn:schemas-microsoft-com:xml-msdata}IsDataSet");
  487. jsonText = JsonConvert.SerializeXNode(a);
  488. Assert.AreEqual(@"{""@msdata:IsDataSet"":""true""}", jsonText);
  489. #endif
  490. // XmlProcessingInstruction
  491. XmlProcessingInstruction instruction = doc.CreateProcessingInstruction("xml-stylesheet", @"href=""classic.xsl"" type=""text/xml""");
  492. jsonText = JsonConvert.SerializeXmlNode(instruction);
  493. Assert.AreEqual(@"{""?xml-stylesheet"":""href=\""classic.xsl\"" type=\""text/xml\""""}", jsonText);
  494. // XmlProcessingInstruction
  495. XmlCDataSection cDataSection = doc.CreateCDataSection("<Kiwi>true</Kiwi>");
  496. jsonText = JsonConvert.SerializeXmlNode(cDataSection);
  497. Assert.AreEqual(@"{""#cdata-section"":""<Kiwi>true</Kiwi>""}", jsonText);
  498. // XmlElement
  499. XmlElement element = doc.CreateElement("xs", "Choice", "http://www.w3.org/2001/XMLSchema");
  500. element.SetAttributeNode(doc.CreateAttribute("msdata", "IsDataSet", "urn:schemas-microsoft-com:xml-msdata"));
  501. XmlAttribute aa = doc.CreateAttribute(@"xmlns", "xs", "http://www.w3.org/2000/xmlns/");
  502. aa.Value = "http://www.w3.org/2001/XMLSchema";
  503. element.SetAttributeNode(aa);
  504. aa = doc.CreateAttribute(@"xmlns", "msdata", "http://www.w3.org/2000/xmlns/");
  505. aa.Value = "urn:schemas-microsoft-com:xml-msdata";
  506. element.SetAttributeNode(aa);
  507. element.AppendChild(instruction);
  508. element.AppendChild(cDataSection);
  509. doc.AppendChild(element);
  510. jsonText = JsonConvert.SerializeXmlNode(element, Formatting.Indented);
  511. StringAssert.AreEqual(@"{
  512. ""xs:Choice"": {
  513. ""@msdata:IsDataSet"": """",
  514. ""@xmlns:xs"": ""http://www.w3.org/2001/XMLSchema"",
  515. ""@xmlns:msdata"": ""urn:schemas-microsoft-com:xml-msdata"",
  516. ""?xml-stylesheet"": ""href=\""classic.xsl\"" type=\""text/xml\"""",
  517. ""#cdata-section"": ""<Kiwi>true</Kiwi>""
  518. }
  519. }", jsonText);
  520. }
  521. [Test]
  522. public void SerializeNodeTypes_Encoding()
  523. {
  524. XmlNode node = DeserializeXmlNode(@"{
  525. ""xs!:Choice!"": {
  526. ""@msdata:IsDataSet!"": """",
  527. ""@xmlns:xs!"": ""http://www.w3.org/2001/XMLSchema"",
  528. ""@xmlns:msdata"": ""urn:schemas-microsoft-com:xml-msdata"",
  529. ""?xml-stylesheet"": ""href=\""classic.xsl\"" type=\""text/xml\"""",
  530. ""#cdata-section"": ""<Kiwi>true</Kiwi>""
  531. }
  532. }");
  533. 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);
  534. string json = SerializeXmlNode(node);
  535. StringAssert.AreEqual(@"{
  536. ""xs!:Choice!"": {
  537. ""@msdata:IsDataSet!"": """",
  538. ""@xmlns:xs!"": ""http://www.w3.org/2001/XMLSchema"",
  539. ""@xmlns:msdata"": ""urn:schemas-microsoft-com:xml-msdata"",
  540. ""?xml-stylesheet"": ""href=\""classic.xsl\"" type=\""text/xml\"""",
  541. ""#cdata-section"": ""<Kiwi>true</Kiwi>""
  542. }
  543. }", json);
  544. }
  545. [Test]
  546. public void DocumentFragmentSerialize()
  547. {
  548. XmlDocument doc = new XmlDocument();
  549. XmlDocumentFragment fragement = doc.CreateDocumentFragment();
  550. fragement.InnerXml = "<Item>widget</Item><Item>widget</Item>";
  551. string jsonText = JsonConvert.SerializeXmlNode(fragement);
  552. string expected = @"{""Item"":[""widget"",""widget""]}";
  553. Assert.AreEqual(expected, jsonText);
  554. }
  555. [Test]
  556. public void XmlDocumentTypeSerialize()
  557. {
  558. 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>";
  559. string expected = @"{
  560. ""?xml"": {
  561. ""@version"": ""1.0"",
  562. ""@encoding"": ""utf-8""
  563. },
  564. ""!DOCTYPE"": {
  565. ""@name"": ""STOCKQUOTE"",
  566. ""@public"": ""-//W3C//DTD StockQuote 1.5//EN"",
  567. ""@system"": ""http://www.idontexistnopenopewhatnope123.org/dtd/stockquote_1.5.dtd""
  568. },
  569. ""STOCKQUOTE"": {
  570. ""@ROWCOUNT"": ""2"",
  571. ""RESULT"": {
  572. ""ROW"": [
  573. {
  574. ""ASK"": ""0"",
  575. ""BID"": ""0"",
  576. ""CHANGE"": ""-16.310"",
  577. ""COMPANYNAME"": ""Dow Jones"",
  578. ""DATETIME"": ""2014-04-17 15:50:37"",
  579. ""DIVIDEND"": ""0"",
  580. ""EPS"": ""0"",
  581. ""EXCHANGE"": """",
  582. ""HIGH"": ""16460.490"",
  583. ""LASTDATETIME"": ""2014-04-17 15:50:37"",
  584. ""LASTPRICE"": ""16408.540"",
  585. ""LOW"": ""16368.140"",
  586. ""OPEN"": ""16424.140"",
  587. ""PCHANGE"": ""-0.099"",
  588. ""PE"": ""0"",
  589. ""PREVIOUSCLOSE"": ""16424.850"",
  590. ""SHARES"": ""0"",
  591. ""TICKER"": ""DJII"",
  592. ""TRADES"": ""0"",
  593. ""VOLUME"": ""136188700"",
  594. ""YEARHIGH"": ""11309.000"",
  595. ""YEARLOW"": ""9302.280"",
  596. ""YIELD"": ""0""
  597. },
  598. {
  599. ""ASK"": ""0"",
  600. ""BID"": ""0"",
  601. ""CHANGE"": ""9.290"",
  602. ""COMPANYNAME"": ""NASDAQ"",
  603. ""DATETIME"": ""2014-04-17 15:40:01"",
  604. ""DIVIDEND"": ""0"",
  605. ""EPS"": ""0"",
  606. ""EXCHANGE"": """",
  607. ""HIGH"": ""4110.460"",
  608. ""LASTDATETIME"": ""2014-04-17 15:40:01"",
  609. ""LASTPRICE"": ""4095.520"",
  610. ""LOW"": ""4064.700"",
  611. ""OPEN"": ""4080.300"",
  612. ""PCHANGE"": ""0.227"",
  613. ""PE"": ""0"",
  614. ""PREVIOUSCLOSE"": ""4086.230"",
  615. ""SHARES"": ""0"",
  616. ""TICKER"": ""COMP"",
  617. ""TRADES"": ""0"",
  618. ""VOLUME"": ""1784210100"",
  619. ""YEARHIGH"": ""4371.710"",
  620. ""YEARLOW"": ""3154.960"",
  621. ""YIELD"": ""0""
  622. }
  623. ]
  624. },
  625. ""STATUS"": ""Couldn't find ticker: SPIC?"",
  626. ""STATUSCODE"": ""2""
  627. }
  628. }";
  629. XmlDocument doc1 = new XmlDocument();
  630. doc1.XmlResolver = null;
  631. doc1.LoadXml(xml);
  632. string json1 = JsonConvert.SerializeXmlNode(doc1, Formatting.Indented);
  633. StringAssert.AreEqual(expected, json1);
  634. XmlDocument doc11 = JsonConvert.DeserializeXmlNode(json1);
  635. StringAssert.AreEqual(xml, ToStringWithDeclaration(doc11));
  636. #if !NET20
  637. XDocument doc2 = XDocument.Parse(xml);
  638. string json2 = JsonConvert.SerializeXNode(doc2, Formatting.Indented);
  639. StringAssert.AreEqual(expected, json2);
  640. XDocument doc22 = JsonConvert.DeserializeXNode(json2);
  641. StringAssert.AreEqual(xml, ToStringWithDeclaration(doc22));
  642. #endif
  643. }
  644. public class Utf8StringWriter : StringWriter
  645. {
  646. public override Encoding Encoding
  647. {
  648. get { return Encoding.UTF8; }
  649. }
  650. public Utf8StringWriter(StringBuilder sb) : base(sb)
  651. {
  652. }
  653. }
  654. #if !NET20
  655. public static string ToStringWithDeclaration(XDocument doc, bool indent = false)
  656. {
  657. StringBuilder builder = new StringBuilder();
  658. using (var writer = XmlWriter.Create(new Utf8StringWriter(builder), new XmlWriterSettings { Indent = indent }))
  659. {
  660. doc.Save(writer);
  661. }
  662. return builder.ToString();
  663. }
  664. #endif
  665. public static string ToStringWithDeclaration(XmlDocument doc, bool indent = false)
  666. {
  667. StringBuilder builder = new StringBuilder();
  668. using (var writer = XmlWriter.Create(new Utf8StringWriter(builder), new XmlWriterSettings { Indent = indent }))
  669. {
  670. doc.Save(writer);
  671. }
  672. return builder.ToString();
  673. }
  674. [Test]
  675. public void NamespaceSerializeDeserialize()
  676. {
  677. string xml = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
  678. <xs:schema xs:id=""SomeID""
  679. xmlns=""""
  680. xmlns:xs=""http://www.w3.org/2001/XMLSchema""
  681. xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
  682. <xs:element name=""MyDataSet"" msdata:IsDataSet=""true"">
  683. <xs:complexType>
  684. <xs:choice maxOccurs=""unbounded"">
  685. <xs:element name=""customers"" >
  686. <xs:complexType >
  687. <xs:sequence>
  688. <xs:element name=""CustomerID"" type=""xs:integer""
  689. minOccurs=""0"" />
  690. <xs:element name=""CompanyName"" type=""xs:string""
  691. minOccurs=""0"" />
  692. <xs:element name=""Phone"" type=""xs:string"" />
  693. </xs:sequence>
  694. </xs:complexType>
  695. </xs:element>
  696. </xs:choice>
  697. </xs:complexType>
  698. </xs:element>
  699. </xs:schema>";
  700. XmlDocument doc = new XmlDocument();
  701. doc.LoadXml(xml);
  702. string jsonText = SerializeXmlNode(doc);
  703. string expected = @"{
  704. ""?xml"": {
  705. ""@version"": ""1.0"",
  706. ""@encoding"": ""utf-8""
  707. },
  708. ""xs:schema"": {
  709. ""@xs:id"": ""SomeID"",
  710. ""@xmlns"": """",
  711. ""@xmlns:xs"": ""http://www.w3.org/2001/XMLSchema"",
  712. ""@xmlns:msdata"": ""urn:schemas-microsoft-com:xml-msdata"",
  713. ""xs:element"": {
  714. ""@name"": ""MyDataSet"",
  715. ""@msdata:IsDataSet"": ""true"",
  716. ""xs:complexType"": {
  717. ""xs:choice"": {
  718. ""@maxOccurs"": ""unbounded"",
  719. ""xs:element"": {
  720. ""@name"": ""customers"",
  721. ""xs:complexType"": {
  722. ""xs:sequence"": {
  723. ""xs:element"": [
  724. {
  725. ""@name"": ""CustomerID"",
  726. ""@type"": ""xs:integer"",
  727. ""@minOccurs"": ""0""
  728. },
  729. {
  730. ""@name"": ""CompanyName"",
  731. ""@type"": ""xs:string"",
  732. ""@minOccurs"": ""0""
  733. },
  734. {
  735. ""@name"": ""Phone"",
  736. ""@type"": ""xs:string""
  737. }
  738. ]
  739. }
  740. }
  741. }
  742. }
  743. }
  744. }
  745. }
  746. }";
  747. StringAssert.AreEqual(expected, jsonText);
  748. XmlDocument deserializedDoc = (XmlDocument)DeserializeXmlNode(jsonText);
  749. Assert.AreEqual(doc.InnerXml, deserializedDoc.InnerXml);
  750. }
  751. [Test]
  752. public void DocumentDeserialize()
  753. {
  754. string jsonText = @"{
  755. ""?xml"": {
  756. ""@version"": ""1.0"",
  757. ""@standalone"": ""no""
  758. },
  759. ""span"": {
  760. ""@class"": ""vevent"",
  761. ""a"": {
  762. ""@class"": ""url"",
  763. ""span"": {
  764. ""@class"": ""summary"",
  765. ""#text"": ""Web 2.0 Conference"",
  766. ""#cdata-section"": ""my escaped text""
  767. },
  768. ""@href"": ""http://www.web2con.com/""
  769. }
  770. }
  771. }";
  772. XmlDocument doc = (XmlDocument)DeserializeXmlNode(jsonText);
  773. string expected = @"<?xml version=""1.0"" standalone=""no""?>
  774. <span class=""vevent"">
  775. <a class=""url"" href=""http://www.web2con.com/"">
  776. <span class=""summary"">Web 2.0 Conference<![CDATA[my escaped text]]></span>
  777. </a>
  778. </span>";
  779. string formattedXml = GetIndentedInnerXml(doc);
  780. StringAssert.AreEqual(expected, formattedXml);
  781. }
  782. private string GetIndentedInnerXml(XmlNode node)
  783. {
  784. XmlWriterSettings settings = new XmlWriterSettings();
  785. settings.Indent = true;
  786. StringWriter sw = new StringWriter();
  787. using (XmlWriter writer = XmlWriter.Create(sw, settings))
  788. {
  789. node.WriteTo(writer);
  790. }
  791. return sw.ToString();
  792. }
  793. [Test]
  794. public void SingleTextNode()
  795. {
  796. string xml = @"<?xml version=""1.0"" standalone=""no""?>
  797. <root>
  798. <person id=""1"">
  799. <name>Alan</name>
  800. <url>http://www.google.com</url>
  801. </person>
  802. <person id=""2"">
  803. <name>Louis</name>
  804. <url>http://www.yahoo.com</url>
  805. </person>
  806. </root>";
  807. XmlDocument doc = new XmlDocument();
  808. doc.LoadXml(xml);
  809. string jsonText = SerializeXmlNode(doc);
  810. XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText);
  811. Assert.AreEqual(doc.InnerXml, newDoc.InnerXml);
  812. }
  813. [Test]
  814. public void EmptyNode()
  815. {
  816. string xml = @"<?xml version=""1.0"" standalone=""no""?>
  817. <root>
  818. <person id=""1"">
  819. <name>Alan</name>
  820. <url />
  821. </person>
  822. <person id=""2"">
  823. <name>Louis</name>
  824. <url>http://www.yahoo.com</url>
  825. </person>
  826. </root>";
  827. XmlDocument doc = new XmlDocument();
  828. doc.LoadXml(xml);
  829. string jsonText = SerializeXmlNode(doc);
  830. StringAssert.AreEqual(@"{
  831. ""?xml"": {
  832. ""@version"": ""1.0"",
  833. ""@standalone"": ""no""
  834. },
  835. ""root"": {
  836. ""person"": [
  837. {
  838. ""@id"": ""1"",
  839. ""name"": ""Alan"",
  840. ""url"": null
  841. },
  842. {
  843. ""@id"": ""2"",
  844. ""name"": ""Louis"",
  845. ""url"": ""http://www.yahoo.com""
  846. }
  847. ]
  848. }
  849. }", jsonText);
  850. XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText);
  851. Assert.AreEqual(doc.InnerXml, newDoc.InnerXml);
  852. }
  853. [Test]
  854. public void OtherElementDataTypes()
  855. {
  856. string jsonText = @"{""?xml"":{""@version"":""1.0"",""@standalone"":""no""},""root"":{""person"":[{""@id"":""1"",""Float"":2.5,""Integer"":99},{""Boolean"":true,""@id"":""2"",""date"":""\/Date(954374400000)\/""}]}}";
  857. XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText);
  858. 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>";
  859. Assert.AreEqual(expected, newDoc.InnerXml);
  860. }
  861. [Test]
  862. public void NoRootObject()
  863. {
  864. ExceptionAssert.Throws<JsonSerializationException>(() => { XmlDocument newDoc = (XmlDocument)JsonConvert.DeserializeXmlNode(@"[1]"); }, "XmlNodeConverter can only convert JSON that begins with an object.");
  865. }
  866. [Test]
  867. public void RootObjectMultipleProperties()
  868. {
  869. ExceptionAssert.Throws<JsonSerializationException>(
  870. () => { XmlDocument newDoc = (XmlDocument)JsonConvert.DeserializeXmlNode(@"{Prop1:1,Prop2:2}"); },
  871. "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.");
  872. }
  873. [Test]
  874. public void JavaScriptConstructor()
  875. {
  876. string jsonText = @"{root:{r:new Date(34343, 55)}}";
  877. XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText);
  878. string expected = @"<root><r><Date>34343</Date><Date>55</Date></r></root>";
  879. Assert.AreEqual(expected, newDoc.InnerXml);
  880. string json = SerializeXmlNode(newDoc);
  881. expected = @"{
  882. ""root"": {
  883. ""r"": {
  884. ""Date"": [
  885. ""34343"",
  886. ""55""
  887. ]
  888. }
  889. }
  890. }";
  891. StringAssert.AreEqual(expected, json);
  892. }
  893. [Test]
  894. public void ForceJsonArray()
  895. {
  896. string arrayXml = @"<root xmlns:json=""http://james.newtonking.com/projects/json"">
  897. <person id=""1"">
  898. <name>Alan</name>
  899. <url>http://www.google.com</url>
  900. <role json:Array=""true"">Admin</role>
  901. </person>
  902. </root>";
  903. XmlDocument arrayDoc = new XmlDocument();
  904. arrayDoc.LoadXml(arrayXml);
  905. string arrayJsonText = SerializeXmlNode(arrayDoc);
  906. string expected = @"{
  907. ""root"": {
  908. ""person"": {
  909. ""@id"": ""1"",
  910. ""name"": ""Alan"",
  911. ""url"": ""http://www.google.com"",
  912. ""role"": [
  913. ""Admin""
  914. ]
  915. }
  916. }
  917. }";
  918. StringAssert.AreEqual(expected, arrayJsonText);
  919. arrayXml = @"<root xmlns:json=""http://james.newtonking.com/projects/json"">
  920. <person id=""1"">
  921. <name>Alan</name>
  922. <url>http://www.google.com</url>
  923. <role json:Array=""true"">Admin1</role>
  924. <role json:Array=""true"">Admin2</role>
  925. </person>
  926. </root>";
  927. arrayDoc = new XmlDocument();
  928. arrayDoc.LoadXml(arrayXml);
  929. arrayJsonText = SerializeXmlNode(arrayDoc);
  930. expected = @"{
  931. ""root"": {
  932. ""person"": {
  933. ""@id"": ""1"",
  934. ""name"": ""Alan"",
  935. ""url"": ""http://www.google.com"",
  936. ""role"": [
  937. ""Admin1"",
  938. ""Admin2""
  939. ]
  940. }
  941. }
  942. }";
  943. StringAssert.AreEqual(expected, arrayJsonText);
  944. arrayXml = @"<root xmlns:json=""http://james.newtonking.com/projects/json"">
  945. <person id=""1"">
  946. <name>Alan</name>
  947. <url>http://www.google.com</url>
  948. <role json:Array=""false"">Admin1</role>
  949. </person>
  950. </root>";
  951. arrayDoc = new XmlDocument();
  952. arrayDoc.LoadXml(arrayXml);
  953. arrayJsonText = SerializeXmlNode(arrayDoc);
  954. expected = @"{
  955. ""root"": {
  956. ""person"": {
  957. ""@id"": ""1"",
  958. ""name"": ""Alan"",
  959. ""url"": ""http://www.google.com"",
  960. ""role"": ""Admin1""
  961. }
  962. }
  963. }";
  964. StringAssert.AreEqual(expected, arrayJsonText);
  965. arrayXml = @"<root>
  966. <person id=""1"">
  967. <name>Alan</name>
  968. <url>http://www.google.com</url>
  969. <role json:Array=""true"" xmlns:json=""http://james.newtonking.com/projects/json"">Admin</role>
  970. </person>
  971. </root>";
  972. arrayDoc = new XmlDocument();
  973. arrayDoc.LoadXml(arrayXml);
  974. arrayJsonText = SerializeXmlNode(arrayDoc);
  975. expected = @"{
  976. ""root"": {
  977. ""person"": {
  978. ""@id"": ""1"",
  979. ""name"": ""Alan"",
  980. ""url"": ""http://www.google.com"",
  981. ""role"": [
  982. ""Admin""
  983. ]
  984. }
  985. }
  986. }";
  987. StringAssert.AreEqual(expected, arrayJsonText);
  988. }
  989. [Test]
  990. public void MultipleRootPropertiesXmlDocument()
  991. {
  992. string json = @"{""count"": 773840,""photos"": null}";
  993. ExceptionAssert.Throws<JsonSerializationException>(
  994. () => { JsonConvert.DeserializeXmlNode(json); },
  995. "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.");
  996. }
  997. #endif
  998. #if !NET20
  999. [Test]
  1000. public void MultipleRootPropertiesXDocument()
  1001. {
  1002. string json = @"{""count"": 773840,""photos"": null}";
  1003. ExceptionAssert.Throws<JsonSerializationException>(
  1004. () => { JsonConvert.DeserializeXNode(json); },
  1005. "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.");
  1006. }
  1007. #endif
  1008. [Test]
  1009. public void MultipleRootPropertiesAddRootElement()
  1010. {
  1011. string json = @"{""count"": 773840,""photos"": 773840}";
  1012. #if !PORTABLE
  1013. XmlDocument newDoc = JsonConvert.DeserializeXmlNode(json, "myRoot");
  1014. Assert.AreEqual(@"<myRoot><count>773840</count><photos>773840</photos></myRoot>", newDoc.InnerXml);
  1015. #endif
  1016. #if !NET20
  1017. XDocument newXDoc = JsonConvert.DeserializeXNode(json, "myRoot");
  1018. Assert.AreEqual(@"<myRoot><count>773840</count><photos>773840</photos></myRoot>", newXDoc.ToString(SaveOptions.DisableFormatting));
  1019. #endif
  1020. }
  1021. [Test]
  1022. public void NestedArrays()
  1023. {
  1024. string json = @"{
  1025. ""available_sizes"": [
  1026. [
  1027. ""assets/images/resized/0001/1070/11070v1-max-150x150.jpg"",
  1028. ""assets/images/resized/0001/1070/11070v1-max-150x150.jpg""
  1029. ],
  1030. [
  1031. ""assets/images/resized/0001/1070/11070v1-max-250x250.jpg"",
  1032. ""assets/images/resized/0001/1070/11070v1-max-250x250.jpg""
  1033. ],
  1034. [
  1035. ""assets/images/resized/0001/1070/11070v1-max-250x250.jpg""
  1036. ]
  1037. ]
  1038. }";
  1039. #if !PORTABLE
  1040. XmlDocument newDoc = JsonConvert.DeserializeXmlNode(json, "myRoot");
  1041. string xml = IndentXml(newDoc.InnerXml);
  1042. StringAssert.AreEqual(@"<myRoot>
  1043. <available_sizes>
  1044. <available_sizes>assets/images/resized/0001/1070/11070v1-max-150x150.jpg</available_sizes>
  1045. <available_sizes>assets/images/resized/0001/1070/11070v1-max-150x150.jpg</available_sizes>
  1046. </available_sizes>
  1047. <available_sizes>
  1048. <available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
  1049. <available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
  1050. </available_sizes>
  1051. <available_sizes>
  1052. <available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
  1053. </available_sizes>
  1054. </myRoot>", IndentXml(newDoc.InnerXml));
  1055. #endif
  1056. #if !NET20
  1057. XDocument newXDoc = JsonConvert.DeserializeXNode(json, "myRoot");
  1058. StringAssert.AreEqual(@"<myRoot>
  1059. <available_sizes>
  1060. <available_sizes>assets/images/resized/0001/1070/11070v1-max-150x150.jpg</available_sizes>
  1061. <available_sizes>assets/images/resized/0001/1070/11070v1-max-150x150.jpg</available_sizes>
  1062. </available_sizes>
  1063. <available_sizes>
  1064. <available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
  1065. <available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
  1066. </available_sizes>
  1067. <available_sizes>
  1068. <available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
  1069. </available_sizes>
  1070. </myRoot>", IndentXml(newXDoc.ToString(SaveOptions.DisableFormatting)));
  1071. #endif
  1072. #if !PORTABLE
  1073. string newJson = JsonConvert.SerializeXmlNode(newDoc, Formatting.Indented);
  1074. Console.WriteLine(newJson);
  1075. #endif
  1076. }
  1077. [Test]
  1078. public void RoundTripNestedArrays()
  1079. {
  1080. string json = @"{
  1081. ""available_sizes"": [
  1082. [
  1083. ""assets/images/resized/0001/1070/11070v1-max-150x150.jpg"",
  1084. ""assets/images/resized/0001/1070/11070v1-max-150x150.jpg""
  1085. ],
  1086. [
  1087. ""assets/images/resized/0001/1070/11070v1-max-250x250.jpg"",
  1088. ""assets/images/resized/0001/1070/11070v1-max-250x250.jpg""
  1089. ],
  1090. [
  1091. ""assets/images/resized/0001/1070/11070v1-max-250x250.jpg""
  1092. ]
  1093. ]
  1094. }";
  1095. #if !PORTABLE
  1096. XmlDocument newDoc = JsonConvert.DeserializeXmlNode(json, "myRoot", true);
  1097. StringAssert.AreEqual(@"<myRoot>
  1098. <available_sizes json:Array=""true"" xmlns:json=""http://james.newtonking.com/projects/json"">
  1099. <available_sizes>assets/images/resized/0001/1070/11070v1-max-150x150.jpg</available_sizes>
  1100. <available_sizes>assets/images/resized/0001/1070/11070v1-max-150x150.jpg</available_sizes>
  1101. </available_sizes>
  1102. <available_sizes json:Array=""true"" xmlns:json=""http://james.newtonking.com/projects/json"">
  1103. <available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
  1104. <available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
  1105. </available_sizes>
  1106. <available_sizes json:Array=""true"" xmlns:json=""http://james.newtonking.com/projects/json"">
  1107. <available_sizes json:Array=""true"">assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
  1108. </available_sizes>
  1109. </myRoot>", IndentXml(newDoc.InnerXml));
  1110. #endif
  1111. #if !NET20
  1112. XDocument newXDoc = JsonConvert.DeserializeXNode(json, "myRoot", true);
  1113. StringAssert.AreEqual(@"<myRoot>
  1114. <available_sizes json:Array=""true"" xmlns:json=""http://james.newtonking.com/projects/json"">
  1115. <available_sizes>assets/images/resized/0001/1070/11070v1-max-150x150.jpg</available_sizes>
  1116. <available_sizes>assets/images/resized/0001/1070/11070v1-max-150x150.jpg</available_sizes>
  1117. </available_sizes>
  1118. <available_sizes json:Array=""true"" xmlns:json=""http://james.newtonking.com/projects/json"">
  1119. <available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
  1120. <available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
  1121. </available_sizes>
  1122. <available_sizes json:Array=""true"" xmlns:json=""http://james.newtonking.com/projects/json"">
  1123. <available_sizes json:Array=""true"">assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
  1124. </available_sizes>
  1125. </myRoot>", IndentXml(newXDoc.ToString(SaveOptions.DisableFormatting)));
  1126. #endif
  1127. #if !PORTABLE
  1128. string newJson = JsonConvert.SerializeXmlNode(newDoc, Formatting.Indented, true);
  1129. StringAssert.AreEqual(json, newJson);
  1130. #endif
  1131. }
  1132. [Test]
  1133. public void MultipleNestedArraysToXml()
  1134. {
  1135. string json = @"{
  1136. ""available_sizes"": [
  1137. [
  1138. [113, 150],
  1139. ""assets/images/resized/0001/1070/11070v1-max-150x150.jpg""
  1140. ],
  1141. [
  1142. [189, 250],
  1143. ""assets/images/resized/0001/1070/11070v1-max-250x250.jpg""
  1144. ],
  1145. [
  1146. [341, 450],
  1147. ""assets/images/resized/0001/1070/11070v1-max-450x450.jpg""
  1148. ]
  1149. ]
  1150. }";
  1151. #if !PORTABLE
  1152. XmlDocument newDoc = JsonConvert.DeserializeXmlNode(json, "myRoot");
  1153. 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);
  1154. #endif
  1155. #if !NET20
  1156. XDocument newXDoc = JsonConvert.DeserializeXNode(json, "myRoot");
  1157. 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));
  1158. #endif
  1159. }
  1160. #if !PORTABLE
  1161. [Test]
  1162. public void Encoding()
  1163. {
  1164. XmlDocument doc = new XmlDocument();
  1165. doc.LoadXml(@"<name>O""Connor</name>"); // i use "" so it will be easier to see the problem
  1166. string json = SerializeXmlNode(doc);
  1167. StringAssert.AreEqual(@"{
  1168. ""name"": ""O\""Connor""
  1169. }", json);
  1170. }
  1171. #endif
  1172. #if !PORTABLE
  1173. [Test]
  1174. public void SerializeComment()
  1175. {
  1176. string xml = @"<span class=""vevent"">
  1177. <a class=""url"" href=""http://www.web2con.com/""><!-- Hi --><span>Text</span></a><!-- Hi! -->
  1178. </span>";
  1179. XmlDocument doc = new XmlDocument();
  1180. doc.LoadXml(xml);
  1181. string jsonText = SerializeXmlNode(doc);
  1182. string expected = @"{
  1183. ""span"": {
  1184. ""@class"": ""vevent"",
  1185. ""a"": {
  1186. ""@class"": ""url"",
  1187. ""@href"": ""http://www.web2con.com/""/* Hi */,
  1188. ""span"": ""Text""
  1189. }/* Hi! */
  1190. }
  1191. }";
  1192. StringAssert.AreEqual(expected, jsonText);
  1193. XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText);
  1194. Assert.AreEqual(@"<span class=""vevent""><a class=""url"" href=""http://www.web2con.com/""><!-- Hi --><span>Text</span></a><!-- Hi! --></span>", newDoc.InnerXml);
  1195. }
  1196. [Test]
  1197. public void SerializeExample()
  1198. {
  1199. string xml = @"<?xml version=""1.0"" standalone=""no""?>
  1200. <root>
  1201. <person id=""1"">
  1202. <name>Alan</name>
  1203. <url>http://www.google.com</url>
  1204. </person>
  1205. <person id=""2"">
  1206. <name>Louis</name>
  1207. <url>http://www.yahoo.com</url>
  1208. </person>
  1209. </root>";
  1210. XmlDocument doc = new XmlDocument();
  1211. doc.LoadXml(xml);
  1212. string jsonText = SerializeXmlNode(doc);
  1213. // {
  1214. // "?xml": {
  1215. // "@version": "1.0",
  1216. // "@standalone": "no"
  1217. // },
  1218. // "root": {
  1219. // "person": [
  1220. // {
  1221. // "@id": "1",
  1222. // "name": "Alan",
  1223. // "url": "http://www.google.com"
  1224. // },
  1225. // {
  1226. // "@id": "2",
  1227. // "name": "Louis",
  1228. // "url": "http://www.yahoo.com"
  1229. // }
  1230. // ]
  1231. // }
  1232. // }
  1233. // format
  1234. jsonText = JObject.Parse(jsonText).ToString();
  1235. StringAssert.AreEqual(@"{
  1236. ""?xml"": {
  1237. ""@version"": ""1.0"",
  1238. ""@standalone"": ""no""
  1239. },
  1240. ""root"": {
  1241. ""person"": [
  1242. {
  1243. ""@id"": ""1"",
  1244. ""name"": ""Alan"",
  1245. ""url"": ""http://www.google.com""
  1246. },
  1247. {
  1248. ""@id"": ""2"",
  1249. ""name"": ""Louis"",
  1250. ""url"": ""http://www.yahoo.com""
  1251. }
  1252. ]
  1253. }
  1254. }", jsonText);
  1255. XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText);
  1256. Assert.AreEqual(doc.InnerXml, newDoc.InnerXml);
  1257. }
  1258. [Test]
  1259. public void DeserializeExample()
  1260. {
  1261. string json = @"{
  1262. ""?xml"": {
  1263. ""@version"": ""1.0"",
  1264. ""@standalone"": ""no""
  1265. },
  1266. ""root"": {
  1267. ""person"": [
  1268. {
  1269. ""@id"": ""1"",
  1270. ""name"": ""Alan"",
  1271. ""url"": ""http://www.google.com""
  1272. },
  1273. {
  1274. ""@id"": ""2"",
  1275. ""name"": ""Louis"",
  1276. ""url"": ""http://www.yahoo.com""
  1277. }
  1278. ]
  1279. }
  1280. }";
  1281. XmlDocument doc = (XmlDocument)DeserializeXmlNode(json);
  1282. // <?xml version="1.0" standalone="no"?>
  1283. // <root>
  1284. // <person id="1">
  1285. // <name>Alan</name>
  1286. // <url>http://www.google.com</url>
  1287. // </person>
  1288. // <person id="2">
  1289. // <name>Louis</name>
  1290. // <url>http://www.yahoo.com</url>
  1291. // </person>
  1292. // </root>
  1293. StringAssert.AreEqual(@"<?xml version=""1.0"" standalone=""no""?><root><person id=""1""><name>Alan</name><url>http://www.google.com</url></person><person id=""2""><name>Louis</name><url>http://www.yahoo.com</url></person></root>", doc.InnerXml);
  1294. }
  1295. [Test]
  1296. public void EscapingNames()
  1297. {
  1298. string json = @"{
  1299. ""root!"": {
  1300. ""person!"": [
  1301. {
  1302. ""@id!"": ""1"",
  1303. ""name!"": ""Alan"",
  1304. ""url!"": ""http://www.google.com""
  1305. },
  1306. {
  1307. ""@id!"": ""2"",
  1308. ""name!"": ""Louis"",
  1309. ""url!"": ""http://www.yahoo.com""
  1310. }
  1311. ]
  1312. }
  1313. }";
  1314. XmlDocument doc = (XmlDocument)DeserializeXmlNode(json);
  1315. Assert.AreEqual(@"<root_x0021_><person_x0021_ id_x0021_=""1""><name_x0021_>Alan</name_x0021_><url_x0021_>http://www.google.com</url_x0021_></person_x0021_><person_x0021_ id_x0021_=""2""><name_x0021_>Louis</name_x0021_><url_x0021_>http://www.yahoo.com</url_x0021_></person_x0021_></root_x0021_>", doc.InnerXml);
  1316. string json2 = SerializeXmlNode(doc);
  1317. StringAssert.AreEqual(@"{
  1318. ""root!"": {
  1319. ""person!"": [
  1320. {
  1321. ""@id!"": ""1"",
  1322. ""name!"": ""Alan"",
  1323. ""url!"": ""http://www.google.com""
  1324. },
  1325. {
  1326. ""@id!"": ""2"",
  1327. ""name!"": ""Louis"",
  1328. ""url!"": ""http://www.yahoo.com""
  1329. }
  1330. ]
  1331. }
  1332. }", json2);
  1333. }
  1334. [Test]
  1335. public void SerializeDeserializeMetadataProperties()
  1336. {
  1337. PreserveReferencesHandlingTests.CircularDictionary circularDictionary = new PreserveReferencesHandlingTests.CircularDictionary();
  1338. circularDictionary.Add("other", new PreserveReferencesHandlingTests.CircularDictionary { { "blah", null } });
  1339. circularDictionary.Add("self", circularDictionary);
  1340. string json = JsonConvert.SerializeObject(circularDictionary, Formatting.Indented,
  1341. new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.All });
  1342. StringAssert.AreEqual(@"{
  1343. ""$id"": ""1"",
  1344. ""other"": {
  1345. ""$id"": ""2"",
  1346. ""blah"": null
  1347. },
  1348. ""self"": {
  1349. ""$ref"": ""1""
  1350. }
  1351. }", json);
  1352. XmlNode node = DeserializeXmlNode(json, "root");
  1353. string xml = GetIndentedInnerXml(node);
  1354. string expected = @"<?xml version=""1.0"" encoding=""utf-16""?>
  1355. <root xmlns:json=""http://james.newtonking.com/projects/json"" json:id=""1"">
  1356. <other json:id=""2"">
  1357. <blah />
  1358. </other>
  1359. <self json:ref=""1"" />
  1360. </root>";
  1361. StringAssert.AreEqual(expected, xml);
  1362. string xmlJson = SerializeXmlNode(node);
  1363. string expectedXmlJson = @"{
  1364. ""root"": {
  1365. ""$id"": ""1"",
  1366. ""other"": {
  1367. ""$id"": ""2"",
  1368. ""blah"": null
  1369. },
  1370. ""self"": {
  1371. ""$ref"": ""1""
  1372. }
  1373. }
  1374. }";
  1375. StringAssert.AreEqual(expectedXmlJson, xmlJson);
  1376. }
  1377. [Test]
  1378. public void SerializeDeserializeMetadataArray()
  1379. {
  1380. string json = @"{
  1381. ""$id"": ""1"",
  1382. ""$values"": [
  1383. ""1"",
  1384. ""2"",
  1385. ""3"",
  1386. ""4"",
  1387. ""5""
  1388. ]
  1389. }";
  1390. XmlNode node = JsonConvert.DeserializeXmlNode(json, "root");
  1391. string xml = GetIndentedInnerXml(node);
  1392. StringAssert.AreEqual(@"<?xml version=""1.0"" encoding=""utf-16""?>
  1393. <root xmlns:json=""http://james.newtonking.com/projects/json"" json:id=""1"">
  1394. <values xmlns=""http://james.newtonking.com/projects/json"">1</values>
  1395. <values xmlns=""http://james.newtonking.com/projects/json"">2</values>
  1396. <values xmlns=""http://james.newtonking.com/projects/json"">3</values>
  1397. <values xmlns=""http://james.newtonking.com/projects/json"">4</values>
  1398. <values xmlns=""http://james.newtonking.com/projects/json"">5</values>
  1399. </root>", xml);
  1400. string newJson = JsonConvert.SerializeXmlNode(node, Formatting.Indented, true);
  1401. StringAssert.AreEqual(json, newJson);
  1402. }
  1403. [Test]
  1404. public void SerializeDeserializeMetadataArrayNoId()
  1405. {
  1406. string json = @"{
  1407. ""$values"": [
  1408. ""1"",
  1409. ""2"",
  1410. ""3"",
  1411. ""4"",
  1412. ""5""
  1413. ]
  1414. }";
  1415. XmlNode node = JsonConvert.DeserializeXmlNode(json, "root");
  1416. string xml = GetIndentedInnerXml(node);
  1417. StringAssert.AreEqual(@"<?xml version=""1.0"" encoding=""utf-16""?>
  1418. <root xmlns:json=""http://james.newtonking.com/projects/json"">
  1419. <values xmlns=""http://james.newtonking.com/projects/json"">1</values>
  1420. <values xmlns=""http://james.newtonking.com/projects/json"">2</values>
  1421. <values xmlns=""http://james.newtonking.com/projects/json"">3</values>
  1422. <values xmlns=""http://james.newtonking.com/projects/json"">4</values>
  1423. <values xmlns=""http://james.newtonking.com/projects/json"">5</values>
  1424. </root>", xml);
  1425. string newJson = JsonConvert.SerializeXmlNode(node, Formatting.Indented, true);
  1426. Console.WriteLine(newJson);
  1427. StringAssert.AreEqual(json, newJson);
  1428. }
  1429. [Test]
  1430. public void SerializeDeserializeMetadataArrayWithIdLast()
  1431. {
  1432. string json = @"{
  1433. ""$values"": [
  1434. ""1"",
  1435. ""2"",
  1436. ""3"",
  1437. ""4"",
  1438. ""5""
  1439. ],
  1440. ""$id"": ""1""
  1441. }";
  1442. XmlNode node = JsonConvert.DeserializeXmlNode(json, "root");
  1443. string xml = GetIndentedInnerXml(node);
  1444. StringAssert.AreEqual(@"<?xml version=""1.0"" encoding=""utf-16""?>
  1445. <root xmlns:json=""http://james.newtonking.com/projects/json"" json:id=""1"">
  1446. <values xmlns=""http://james.newtonking.com/projects/json"">1</values>
  1447. <values xmlns=""http://james.newtonking.com/projects/json"">2</values>
  1448. <values xmlns=""http://james.newtonking.com/projects/json"">3</values>
  1449. <values xmlns=""http://james.newtonking.com/projects/json"">4</values>
  1450. <values xmlns=""http://james.newtonking.com/projects/json"">5</values>
  1451. </root>", xml);
  1452. string newJson = JsonConvert.SerializeXmlNode(node, Formatting.Indented, true);
  1453. StringAssert.AreEqual(@"{
  1454. ""$id"": ""1"",
  1455. ""$values"": [
  1456. ""1"",
  1457. ""2"",
  1458. ""3"",
  1459. ""4"",
  1460. ""5""
  1461. ]
  1462. }", newJson);
  1463. }
  1464. [Test]
  1465. public void SerializeMetadataPropertyWithBadValue()
  1466. {
  1467. string json = @"{
  1468. ""$id"": []
  1469. }";
  1470. ExceptionAssert.Throws<JsonSerializationException>(
  1471. () => { JsonConvert.DeserializeXmlNode(json, "root"); },
  1472. "Unexpected JsonToken: StartArray. Path '$id', line 2, position 10.");
  1473. }
  1474. [Test]
  1475. public void SerializeDeserializeMetadataWithNullValue()
  1476. {
  1477. string json = @"{
  1478. ""$id"": null
  1479. }";
  1480. XmlNode node = JsonConvert.DeserializeXmlNode(json, "root");
  1481. string xml = GetIndentedInnerXml(node);
  1482. StringAssert.AreEqual(@"<?xml version=""1.0"" encoding=""utf-16""?>
  1483. <root xmlns:json=""http://james.newtonking.com/projects/json"" json:id="""" />", xml);
  1484. string newJson = JsonConvert.SerializeXmlNode(node, Formatting.Indented, true);
  1485. StringAssert.AreEqual(@"{
  1486. ""$id"": """"
  1487. }", newJson);
  1488. }
  1489. [Test]
  1490. public void SerializeDeserializeMetadataArrayNull()
  1491. {
  1492. string json = @"{
  1493. ""$id"": ""1"",
  1494. ""$values"": null
  1495. }";
  1496. XmlNode node = JsonConvert.DeserializeXmlNode(json, "root");
  1497. string xml = GetIndentedInnerXml(node);
  1498. StringAssert.AreEqual(@"<?xml version=""1.0"" encoding=""utf-16""?>
  1499. <root xmlns:json=""http://james.newtonking.com/projects/json"" json:id=""1"">
  1500. <values xmlns=""http://james.newtonking.com/projects/json"" />
  1501. </root>", xml);
  1502. string newJson = JsonConvert.SerializeXmlNode(node, Formatting.Indented, true);
  1503. StringAssert.AreEqual(json, newJson);
  1504. }
  1505. [Test]
  1506. public void EmptyPropertyName()
  1507. {
  1508. string json = @"{
  1509. ""8452309520V2"": {
  1510. """": {
  1511. ""CLIENT"": {
  1512. ""ID_EXPIRATION_1"": {
  1513. ""VALUE"": ""12/12/2000"",
  1514. ""DATATYPE"": ""D"",
  1515. ""MSG"": ""Missing Identification Exp. Date 1""
  1516. },
  1517. ""ID_ISSUEDATE_1"": {
  1518. ""VALUE"": """",
  1519. ""DATATYPE"": ""D"",
  1520. ""MSG"": ""Missing Identification Issue Date 1""
  1521. }
  1522. }
  1523. },
  1524. ""457463534534"": {
  1525. ""ACCOUNT"": {
  1526. ""FUNDING_SOURCE"": {
  1527. ""VALUE"": ""FS0"",
  1528. ""DATATYPE"": ""L"",
  1529. ""MSG"": ""Missing Source of Funds""
  1530. }
  1531. }
  1532. }
  1533. }
  1534. }{
  1535. ""34534634535345"": {
  1536. """": {
  1537. ""CLIENT"": {
  1538. ""ID_NUMBER_1"": {
  1539. ""VALUE"": """",
  1540. ""DATATYPE"": ""S"",
  1541. ""MSG"": ""Missing Picture ID""
  1542. },
  1543. ""ID_EXPIRATION_1"": {
  1544. ""VALUE"": ""12/12/2000"",
  1545. ""DATATYPE"": ""D"",
  1546. ""MSG"": ""Missing Picture ID""
  1547. },
  1548. ""WALK_IN"": {
  1549. ""VALUE"": """",
  1550. ""DATATYPE"": ""L"",
  1551. ""MSG"": ""Missing Walk in""
  1552. },
  1553. ""PERSONAL_MEETING"": {
  1554. ""VALUE"": ""PM1"",
  1555. ""DATATYPE"": ""L"",
  1556. ""MSG"": ""Missing Met Client in Person""
  1557. },
  1558. ""ID_ISSUEDATE_1"": {
  1559. ""VALUE"": """",
  1560. ""DATATYPE"": ""D"",
  1561. ""MSG"": ""Missing Picture ID""
  1562. },
  1563. ""PHOTO_ID"": {
  1564. ""VALUE"": """",
  1565. ""DATATYPE"": ""L"",
  1566. ""MSG"": ""Missing Picture ID""
  1567. },
  1568. ""ID_TYPE_1"": {
  1569. ""VALUE"": """",
  1570. ""DATATYPE"": ""L"",
  1571. ""MSG"": ""Missing Picture ID""
  1572. }
  1573. }
  1574. },
  1575. ""45635624523"": {
  1576. ""ACCOUNT"": {
  1577. ""FUNDING_SOURCE"": {
  1578. ""VALUE"": ""FS1"",
  1579. ""DATATYPE"": ""L"",
  1580. ""MSG"": ""Missing Source of Funds""
  1581. }
  1582. }
  1583. }
  1584. }
  1585. }";
  1586. ExceptionAssert.Throws<JsonSerializationException>(
  1587. () => { DeserializeXmlNode(json); },
  1588. "XmlNodeConverter cannot convert JSON with an empty property name to XML. Path '8452309520V2.', line 3, position 9.");
  1589. }
  1590. [Test]
  1591. public void SingleItemArrayPropertySerialization()
  1592. {
  1593. Product product = new Product();
  1594. product.Name = "Apple";
  1595. product.ExpiryDate = new DateTime(2008, 12, 28, 0, 0, 0, DateTimeKind.Utc);
  1596. product.Price = 3.99M;
  1597. product.Sizes = new string[] { "Small" };
  1598. string output = JsonConvert.SerializeObject(product, new IsoDateTimeConverter());
  1599. XmlDocument xmlProduct = JsonConvert.DeserializeXmlNode(output, "product", true);
  1600. StringAssert.AreEqual(@"<product>
  1601. <Name>Apple</Name>
  1602. <ExpiryDate>2008-12-28T00:00:00Z</ExpiryDate>
  1603. <Price>3.99</Price>
  1604. <Sizes json:Array=""true"" xmlns:json=""http://james.newtonking.com/projects/json"">Small</Sizes>
  1605. </product>", IndentXml(xmlProduct.InnerXml));
  1606. string output2 = JsonConvert.SerializeXmlNode(xmlProduct.DocumentElement, Formatting.Indented);
  1607. StringAssert.AreEqual(@"{
  1608. ""product"": {
  1609. ""Name"": ""Apple"",
  1610. ""ExpiryDate"": ""2008-12-28T00:00:00Z"",
  1611. ""Price"": ""3.99"",
  1612. ""Sizes"": [
  1613. ""Small""
  1614. ]
  1615. }
  1616. }", output2);
  1617. }
  1618. public class TestComplexArrayClass
  1619. {
  1620. public string Name { get; set; }
  1621. public IList<Product> Products { get; set; }
  1622. }
  1623. [Test]
  1624. public void ComplexSingleItemArrayPropertySerialization()
  1625. {
  1626. TestComplexArrayClass o = new TestComplexArrayClass
  1627. {
  1628. Name = "Hi",
  1629. Products = new List<Product>
  1630. {
  1631. new Product { Name = "First" }
  1632. }
  1633. };
  1634. string output = JsonConvert.SerializeObject(o, new IsoDateTimeConverter());
  1635. XmlDocument xmlProduct = JsonConvert.DeserializeXmlNode(output, "test", true);
  1636. StringAssert.AreEqual(@"<test>
  1637. <Name>Hi</Name>
  1638. <Products json:Array=""true"" xmlns:json=""http://james.newtonking.com/projects/json"">
  1639. <Name>First</Name>
  1640. <ExpiryDate>2000-01-01T00:00:00Z</ExpiryDate>
  1641. <Price>0</Price>
  1642. <Sizes />
  1643. </Products>
  1644. </test>", IndentXml(xmlProduct.InnerXml));
  1645. string output2 = JsonConvert.SerializeXmlNode(xmlProduct.DocumentElement, Formatting.Indented, true);
  1646. StringAssert.AreEqual(@"{
  1647. ""Name"": ""Hi"",
  1648. ""Products"": [
  1649. {
  1650. ""Name"": ""First"",
  1651. ""ExpiryDate"": ""2000-01-01T00:00:00Z"",
  1652. ""Price"": ""0"",
  1653. ""Sizes"": null
  1654. }
  1655. ]
  1656. }", output2);
  1657. }
  1658. [Test]
  1659. public void OmitRootObject()
  1660. {
  1661. string xml = @"<test>
  1662. <Name>Hi</Name>
  1663. <Name>Hi</Name>
  1664. <Products json:Array=""true"" xmlns:json=""http://james.newtonking.com/projects/json"">
  1665. <Name>First</Name>
  1666. <ExpiryDate>2000-01-01T00:00:00Z</ExpiryDate>
  1667. <Price>0</Price>
  1668. <Sizes />
  1669. </Products>
  1670. </test>";
  1671. XmlDocument d = new XmlDocument();
  1672. d.LoadXml(xml);
  1673. string output = JsonConvert.SerializeXmlNode(d, Formatting.Indented, true);
  1674. StringAssert.AreEqual(@"{
  1675. ""Name"": [
  1676. ""Hi"",
  1677. ""Hi""
  1678. ],
  1679. ""Products"": [
  1680. {
  1681. ""Name"": ""First"",
  1682. ""ExpiryDate"": ""2000-01-01T00:00:00Z"",
  1683. ""Price"": ""0"",
  1684. ""Sizes"": null
  1685. }
  1686. ]
  1687. }", output);
  1688. }
  1689. [Test]
  1690. public void EmtpyElementWithArrayAttributeShouldWriteAttributes()
  1691. {
  1692. string xml = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
  1693. <root xmlns:json=""http://james.newtonking.com/projects/json"">
  1694. <A>
  1695. <B name=""sample"" json:Array=""true""/>
  1696. <C></C>
  1697. <C></C>
  1698. </A>
  1699. </root>";
  1700. XmlDocument d = new XmlDocument();
  1701. d.LoadXml(xml);
  1702. string json = JsonConvert.SerializeXmlNode(d, Formatting.Indented);
  1703. StringAssert.AreEqual(@"{
  1704. ""?xml"": {
  1705. ""@version"": ""1.0"",
  1706. ""@encoding"": ""utf-8""
  1707. },
  1708. ""root"": {
  1709. ""A"": {
  1710. ""B"": [
  1711. {
  1712. ""@name"": ""sample""
  1713. }
  1714. ],
  1715. ""C"": [
  1716. """",
  1717. """"
  1718. ]
  1719. }
  1720. }
  1721. }", json);
  1722. XmlDocument d2 = JsonConvert.DeserializeXmlNode(json);
  1723. StringAssert.AreEqual(@"<?xml version=""1.0"" encoding=""utf-8""?>
  1724. <root>
  1725. <A>
  1726. <B name=""sample"" />
  1727. <C></C>
  1728. <C></C>
  1729. </A>
  1730. </root>", ToStringWithDeclaration(d2, true));
  1731. }
  1732. [Test]
  1733. public void EmtpyElementWithArrayAttributeShouldWriteElement()
  1734. {
  1735. string xml = @"<root>
  1736. <Reports d1p1:Array=""true"" xmlns:d1p1=""http://james.newtonking.com/projects/json"" />
  1737. </root>";
  1738. XmlDocument d = new XmlDocument();
  1739. d.LoadXml(xml);
  1740. string json = JsonConvert.SerializeXmlNode(d, Formatting.Indented);
  1741. StringAssert.AreEqual(@"{
  1742. ""root"": {
  1743. ""Reports"": [
  1744. {}
  1745. ]
  1746. }
  1747. }", json);
  1748. }
  1749. [Test]
  1750. public void DeserializeNonInt64IntegerValues()
  1751. {
  1752. var dict = new Dictionary<string, object> { { "Int16", (short)1 }, { "Float", 2f }, { "Int32", 3 } };
  1753. var obj = JObject.FromObject(dict);
  1754. var serializer = JsonSerializer.Create(new JsonSerializerSettings { Converters = { new XmlNodeConverter() { DeserializeRootElementName = "root" } } });
  1755. using (var reader = obj.CreateReader())
  1756. {
  1757. var value = (XmlDocument)serializer.Deserialize(reader, typeof(XmlDocument));
  1758. Assert.AreEqual(@"<root><Int16>1</Int16><Float>2</Float><Int32>3</Int32></root>", value.InnerXml);
  1759. }
  1760. }
  1761. [Test]
  1762. public void DeserializingBooleanValues()
  1763. {
  1764. MemoryStream ms = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(@"{root:{""@booleanType"":true}}"));
  1765. MemoryStream xml = new MemoryStream();
  1766. JsonBodyToSoapXml(ms, xml);
  1767. string xmlString = System.Text.Encoding.UTF8.GetString(xml.ToArray());
  1768. Assert.AreEqual(@"<?xml version=""1.0"" encoding=""utf-8""?><root booleanType=""true"" />", xmlString);
  1769. }
  1770. private static void JsonBodyToSoapXml(Stream json, Stream xml)
  1771. {
  1772. Newtonsoft.Json.JsonSerializerSettings settings = new Newtonsoft.Json.JsonSerializerSettings();
  1773. settings.Converters.Add(new Newtonsoft.Json.Converters.XmlNodeConverter());
  1774. Newtonsoft.Json.JsonSerializer serializer = Newtonsoft.Json.JsonSerializer.Create(settings);
  1775. using (Newtonsoft.Json.JsonTextReader reader = new Newtonsoft.Json.JsonTextReader(new System.IO.StreamReader(json)))
  1776. {
  1777. XmlDocument doc = (XmlDocument)serializer.Deserialize(reader, typeof(XmlDocument));
  1778. if (reader.Read() && reader.TokenType != JsonToken.Comment)
  1779. {
  1780. throw new JsonSerializationException("Additional text found in JSON string after finishing deserializing object.");
  1781. }
  1782. using (XmlWriter writer = XmlWriter.Create(xml))
  1783. {
  1784. doc.Save(writer);
  1785. }
  1786. }
  1787. }
  1788. #endif
  1789. #if !NET20
  1790. [Test]
  1791. public void DeserializeXNodeDefaultNamespace()
  1792. {
  1793. string xaml = @"<Grid xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" xmlns:toolkit=""clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"" Style=""{StaticResource trimFormGrid}"" x:Name=""TrimObjectForm"">
  1794. <Grid.ColumnDefinitions>
  1795. <ColumnDefinition Width=""63*"" />
  1796. <ColumnDefinition Width=""320*"" />
  1797. </Grid.ColumnDefinitions>
  1798. <Grid.RowDefinitions xmlns="""">
  1799. <RowDefinition />
  1800. <RowDefinition />
  1801. <RowDefinition />
  1802. <RowDefinition />
  1803. <RowDefinition />
  1804. <RowDefinition />
  1805. <RowDefinition />
  1806. <RowDefinition />
  1807. </Grid.RowDefinitions>
  1808. <TextBox Style=""{StaticResource trimFormGrid_TB}"" Text=""{Binding TypedTitle, Converter={StaticResource trimPropertyConverter}}"" Name=""RecordTypedTitle"" Grid.Column=""1"" Grid.Row=""0"" xmlns="""" />
  1809. <TextBox Style=""{StaticResource trimFormGrid_TB}"" Text=""{Binding ExternalReference, Converter={StaticResource trimPropertyConverter}}"" Name=""RecordExternalReference"" Grid.Column=""1"" Grid.Row=""1"" xmlns="""" />
  1810. <toolkit:DatePicker Style=""{StaticResource trimFormGrid_DP}"" Value=""{Binding DateCreated, Converter={StaticResource trimPropertyConverter}}"" Name=""RecordDateCreated"" Grid.Column=""1"" Grid.Row=""2"" />
  1811. <toolkit:DatePicker Style=""{StaticResource trimFormGrid_DP}"" Value=""{Binding DateDue, Converter={StaticResource trimPropertyConverter}}"" Name=""RecordDateDue"" Grid.Column=""1"" Grid.Row=""3"" />
  1812. <TextBox Style=""{StaticResource trimFormGrid_TB}"" Text=""{Binding Author, Converter={StaticResource trimPropertyConverter}}"" Name=""RecordAuthor"" Grid.Column=""1"" Grid.Row=""4"" xmlns="""" />
  1813. <TextBox Style=""{StaticResource trimFormGrid_TB}"" Text=""{Binding Container, Converter={StaticResource trimPropertyConverter}}"" Name=""RecordContainer"" Grid.Column=""1"" Grid.Row=""5"" xmlns="""" />
  1814. <TextBox Style=""{StaticResource trimFormGrid_TB}"" Text=""{Binding IsEnclosed, Converter={StaticResource trimPropertyConverter}}"" Name=""RecordIsEnclosed"" Grid.Column=""1"" Grid.Row=""6"" xmlns="""" />
  1815. <TextBox Style=""{StaticResource trimFormGrid_TB}"" Text=""{Binding Assignee, Converter={StaticResource trimPropertyConverter}}"" Name=""RecordAssignee"" Grid.Column=""1"" Grid.Row=""7"" xmlns="""" />
  1816. <TextBlock Grid.Column=""0"" Text=""Title (Free Text Part)"" Style=""{StaticResource trimFormGrid_LBL}"" Grid.Row=""0"" xmlns="""" />
  1817. <TextBlock Grid.Column=""0"" Text=""External ID"" Style=""{StaticResource trimFormGrid_LBL}"" Grid.Row=""1"" xmlns="""" />
  1818. <TextBlock Grid.Column=""0"" Text=""Date Created"" Style=""{StaticResource trimFormGrid_LBL}"" Grid.Row=""2"" xmlns="""" />
  1819. <TextBlock Grid.Column=""0"" Text=""Date Due"" Style=""{StaticResource trimFormGrid_LBL}"" Grid.Row=""3"" xmlns="""" />
  1820. <TextBlock Grid.Column=""0"" Text=""Author"" Style=""{StaticResource trimFormGrid_LBL}"" Grid.Row=""4"" xmlns="""" />
  1821. <TextBlock Grid.Column=""0"" Text=""Container"" Style=""{StaticResource trimFormGrid_LBL}"" Grid.Row=""5"" xmlns="""" />
  1822. <TextBlock Grid.Column=""0"" Text=""Enclosed?"" Style=""{StaticResource trimFormGrid_LBL}"" Grid.Row=""6"" xmlns="""" />
  1823. <TextBlock Grid.Column=""0"" Text=""Assignee"" Style=""{StaticResource trimFormGrid_LBL}"" Grid.Row=""7"" xmlns="""" />
  1824. </Grid>";
  1825. string json = JsonConvert.SerializeXNode(XDocument.Parse(xaml), Formatting.Indented);
  1826. string expectedJson = @"{
  1827. ""Grid"": {
  1828. ""@xmlns"": ""http://schemas.microsoft.com/winfx/2006/xaml/presentation"",
  1829. ""@xmlns:x"": ""http://schemas.microsoft.com/winfx/2006/xaml"",
  1830. ""@xmlns:toolkit"": ""clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"",
  1831. ""@Style"": ""{StaticResource trimFormGrid}"",
  1832. ""@x:Name"": ""TrimObjectForm"",
  1833. ""Grid.ColumnDefinitions"": {
  1834. ""ColumnDefinition"": [
  1835. {
  1836. ""@Width"": ""63*""
  1837. },
  1838. {
  1839. ""@Width"": ""320*""
  1840. }
  1841. ]
  1842. },
  1843. ""Grid.RowDefinitions"": {
  1844. ""@xmlns"": """",
  1845. ""RowDefinition"": [
  1846. null,
  1847. null,
  1848. null,
  1849. null,
  1850. null,
  1851. null,
  1852. null,
  1853. null
  1854. ]
  1855. },
  1856. ""TextBox"": [
  1857. {
  1858. ""@Style"": ""{StaticResource trimFormGrid_TB}"",
  1859. ""@Text"": ""{Binding TypedTitle, Converter={StaticResource trimPropertyConverter}}"",
  1860. ""@Name"": ""RecordTypedTitle"",
  1861. ""@Grid.Column"": ""1"",
  1862. ""@Grid.Row"": ""0"",
  1863. ""@xmlns"": """"
  1864. },
  1865. {
  1866. ""@Style"": ""{StaticResource trimFormGrid_TB}"",
  1867. ""@Text"": ""{Binding ExternalReference, Converter={StaticResource trimPropertyConverter}}"",
  1868. ""@Name"": ""RecordExternalReference"",
  1869. ""@Grid.Column"": ""1"",
  1870. ""@Grid.Row"": ""1"",
  1871. ""@xmlns"": """"
  1872. },
  1873. {
  1874. ""@Style"": ""{StaticResource trimFormGrid_TB}"",
  1875. ""@Text"": ""{Binding Author, Converter={StaticResource trimPropertyConverter}}"",
  1876. ""@Name"": ""RecordAuthor"",
  1877. ""@Grid.Column"": ""1"",
  1878. ""@Grid.Row"": ""4"",
  1879. ""@xmlns"": """"
  1880. },
  1881. {
  1882. ""@Style"": ""{StaticResource trimFormGrid_TB}"",
  1883. ""@Text"": ""{Binding Container, Converter={StaticResource trimPropertyConverter}}"",
  1884. ""@Name"": ""RecordContainer"",
  1885. ""@Grid.Column"": ""1"",
  1886. ""@Grid.Row"": ""5"",
  1887. ""@xmlns"": """"
  1888. },
  1889. {
  1890. ""@Style"": ""{StaticResource trimFormGrid_TB}"",
  1891. ""@Text"": ""{Binding IsEnclosed, Converter={StaticResource trimPropertyConverter}}"",
  1892. ""@Name"": ""RecordIsEnclosed"",
  1893. ""@Grid.Column"": ""1"",
  1894. ""@Grid.Row"": ""6"",
  1895. ""@xmlns"": """"
  1896. },
  1897. {
  1898. ""@Style"": ""{StaticResource trimFormGrid_TB}"",
  1899. ""@Text"": ""{Binding Assignee, Converter={StaticResource trimPropertyConverter}}"",
  1900. ""@Name"": ""RecordAssignee"",
  1901. ""@Grid.Column"": ""1"",
  1902. ""@Grid.Row"": ""7"",
  1903. ""@xmlns"": """"
  1904. }
  1905. ],
  1906. ""toolkit:DatePicker"": [
  1907. {
  1908. ""@Style"": ""{StaticResource trimFormGrid_DP}"",
  1909. ""@Value"": ""{Binding DateCreated, Converter={StaticResource trimPropertyConverter}}"",
  1910. ""@Name"": ""RecordDateCreated"",
  1911. ""@Grid.Column"": ""1"",
  1912. ""@Grid.Row"": ""2""
  1913. },
  1914. {
  1915. ""@Style"": ""{StaticResource trimFormGrid_DP}"",
  1916. ""@Value"": ""{Binding DateDue, Converter={StaticResource trimPropertyConverter}}"",
  1917. ""@Name"": ""RecordDateDue"",
  1918. ""@Grid.Column"": ""1"",
  1919. ""@Grid.Row"": ""3""
  1920. }
  1921. ],
  1922. ""TextBlock"": [
  1923. {
  1924. ""@Grid.Column"": ""0"",
  1925. ""@Text"": ""Title (Free Text Part)"",
  1926. ""@Style"": ""{StaticResource trimFormGrid_LBL}"",
  1927. ""@Grid.Row"": ""0"",
  1928. ""@xmlns"": """"
  1929. },
  1930. {
  1931. ""@Grid.Column"": ""0"",
  1932. ""@Text"": ""External ID"",
  1933. ""@Style"": ""{StaticResource trimFormGrid_LBL}"",
  1934. ""@Grid.Row"": ""1"",
  1935. ""@xmlns"": """"
  1936. },
  1937. {
  1938. ""@Grid.Column"": ""0"",
  1939. ""@Text"": ""Date Created"",
  1940. ""@Style"": ""{StaticResource trimFormGrid_LBL}"",
  1941. ""@Grid.Row"": ""2"",
  1942. ""@xmlns"": """"
  1943. },
  1944. {
  1945. ""@Grid.Column"": ""0"",
  1946. ""@Text"": ""Date Due"",
  1947. ""@Style"": ""{StaticResource trimFormGrid_LBL}"",
  1948. ""@Grid.Row"": ""3"",
  1949. ""@xmlns"": """"
  1950. },
  1951. {
  1952. ""@Grid.Column"": ""0"",
  1953. ""@Text"": ""Author"",
  1954. ""@Style"": ""{StaticResource trimFormGrid_LBL}"",
  1955. ""@Grid.Row"": ""4"",
  1956. ""@xmlns"": """"
  1957. },
  1958. {
  1959. ""@Grid.Column"": ""0"",
  1960. ""@Text"": ""Container"",
  1961. ""@Style"": ""{StaticResource trimFormGrid_LBL}"",
  1962. ""@Grid.Row"": ""5"",
  1963. ""@xmlns"": """"
  1964. },
  1965. {
  1966. ""@Grid.Column"": ""0"",
  1967. ""@Text"": ""Enclosed?"",
  1968. ""@Style"": ""{StaticResource trimFormGrid_LBL}"",
  1969. ""@Grid.Row"": ""6"",
  1970. ""@xmlns"": """"
  1971. },
  1972. {
  1973. ""@Grid.Column"": ""0"",
  1974. ""@Text"": ""Assignee"",
  1975. ""@Style"": ""{StaticResource trimFormGrid_LBL}"",
  1976. ""@Grid.Row"": ""7"",
  1977. ""@xmlns"": """"
  1978. }
  1979. ]
  1980. }
  1981. }";
  1982. StringAssert.AreEqual(expectedJson, json);
  1983. XNode node = JsonConvert.DeserializeXNode(json);
  1984. string xaml2 = node.ToString();
  1985. string expectedXaml = @"<Grid xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" xmlns:toolkit=""clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"" Style=""{StaticResource trimFormGrid}"" x:Name=""TrimObjectForm"">
  1986. <Grid.ColumnDefinitions>
  1987. <ColumnDefinition Width=""63*"" />
  1988. <ColumnDefinition Width=""320*"" />
  1989. </Grid.ColumnDefinitions>
  1990. <Grid.RowDefinitions xmlns="""">
  1991. <RowDefinition />
  1992. <RowDefinition />
  1993. <RowDefinition />
  1994. <RowDefinition />
  1995. <RowDefinition />
  1996. <RowDefinition />
  1997. <RowDefinition />
  1998. <RowDefinition />
  1999. </Grid.RowDefinitions>
  2000. <TextBox Style=""{StaticResource trimFormGrid_TB}"" Text=""{Binding TypedTitle, Converter={StaticResource trimPropertyConverter}}"" Name=""RecordTypedTitle"" Grid.Column=""1"" Grid.Row=""0"" xmlns="""" />
  2001. <TextBox Style=""{StaticResource trimFormGrid_TB}"" Text=""{Binding ExternalReference, Converter={StaticResource trimPropertyConverter}}"" Name=""RecordExternalReference"" Grid.Column=""1"" Grid.Row=""1"" xmlns="""" />
  2002. <TextBox Style=""{StaticResource trimFormGrid_TB}"" Text=""{Binding Author, Converter={StaticResource trimPropertyConverter}}"" Name=""RecordAuthor"" Grid.Column=""1"" Grid.Row=""4"" xmlns="""" />
  2003. <TextBox Style=""{StaticResource trimFormGrid_TB}"" Text=""{Binding Container, Converter={StaticResource trimPropertyConverter}}"" Name=""RecordContainer"" Grid.Column=""1"" Grid.Row=""5"" xmlns="""" />
  2004. <TextBox Style=""{StaticResource trimFormGrid_TB}"" Text=""{Binding IsEnclosed, Converter={StaticResource trimPropertyConverter}}"" Name=""RecordIsEnclosed"" Grid.Column=""1"" Grid.Row=""6"" xmlns="""" />
  2005. <TextBox Style=""{StaticResource trimFormGrid_TB}"" Text=""{Binding Assignee, Converter={StaticResource trimPropertyConverter}}"" Name=""RecordAssignee"" Grid.Column=""1"" Grid.Row=""7"" xmlns="""" />
  2006. <toolkit:DatePicker Style=""{StaticResource trimFormGrid_DP}"" Value=""{Binding DateCreated, Converter={StaticResource trimPropertyConverter}}"" Name=""RecordDateCreated"" Grid.Column=""1"" Grid.Row=""2"" />
  2007. <toolkit:DatePicker Style=""{StaticResource trimFormGrid_DP}"" Value=""{Binding DateDue, Converter={StaticResource trimPropertyConverter}}"" Name=""RecordDateDue"" Grid.Column=""1"" Grid.Row=""3"" />
  2008. <TextBlock Grid.Column=""0"" Text=""Title (Free Text Part)"" Style=""{StaticResource trimFormGrid_LBL}"" Grid.Row=""0"" xmlns="""" />
  2009. <TextBlock Grid.Column=""0"" Text=""External ID"" Style=""{StaticResource trimFormGrid_LBL}"" Grid.Row=""1"" xmlns="""" />
  2010. <TextBlock Grid.Column=""0"" Text=""Date Created"" Style=""{StaticResource trimFormGrid_LBL}"" Grid.Row=""2"" xmlns="""" />
  2011. <TextBlock Grid.Column=""0"" Text=""Date Due"" Style=""{StaticResource trimFormGrid_LBL}"" Grid.Row=""3"" xmlns="""" />
  2012. <TextBlock Grid.Column=""0"" Text=""Author"" Style=""{StaticResource trimFormGrid_LBL}"" Grid.Row=""4"" xmlns="""" />
  2013. <TextBlock Grid.Column=""0"" Text=""Container"" Style=""{StaticResource trimFormGrid_LBL}"" Grid.Row=""5"" xmlns="""" />
  2014. <TextBlock Grid.Column=""0"" Text=""Enclosed?"" Style=""{StaticResource trimFormGrid_LBL}"" Grid.Row=""6"" xmlns="""" />
  2015. <TextBlock Grid.Column=""0"" Text=""Assignee"" Style=""{StaticResource trimFormGrid_LBL}"" Grid.Row=""7"" xmlns="""" />
  2016. </Grid>";
  2017. StringAssert.AreEqual(expectedXaml, xaml2);
  2018. }
  2019. #endif
  2020. #if !PORTABLE
  2021. [Test]
  2022. public void DeserializeXmlNodeDefaultNamespace()
  2023. {
  2024. string xaml = @"<Grid xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" xmlns:toolkit=""clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"" Style=""{StaticResource trimFormGrid}"" x:Name=""TrimObjectForm"">
  2025. <Grid.ColumnDefinitions>
  2026. <ColumnDefinition Width=""63*"" />
  2027. <ColumnDefinition Width=""320*"" />
  2028. </Grid.ColumnDefinitions>
  2029. <Grid.RowDefinitions xmlns="""">
  2030. <RowDefinition />
  2031. <RowDefinition />
  2032. <RowDefinition />
  2033. <RowDefinition />
  2034. <RowDefinition />
  2035. <RowDefinition />
  2036. <RowDefinition />
  2037. <RowDefinition />
  2038. </Grid.RowDefinitions>
  2039. <TextBox Style=""{StaticResource trimFormGrid_TB}"" Text=""{Binding TypedTitle, Converter={StaticResource trimPropertyConverter}}"" Name=""RecordTypedTitle"" Grid.Column=""1"" Grid.Row=""0"" xmlns="""" />
  2040. <TextBox Style=""{StaticResource trimFormGrid_TB}"" Text=""{Binding ExternalReference, Converter={StaticResource trimPropertyConverter}}"" Name=""RecordExternalReference"" Grid.Column=""1"" Grid.Row=""1"" xmlns="""" />
  2041. <toolkit:DatePicker Style=""{StaticResource trimFormGrid_DP}"" Value=""{Binding DateCreated, Converter={StaticResource trimPropertyConverter}}"" Name=""RecordDateCreated"" Grid.Column=""1"" Grid.Row=""2"" />
  2042. <toolkit:DatePicker Style=""{StaticResource trimFormGrid_DP}"" Value=""{Binding DateDue, Converter={StaticResource trimPropertyConverter}}"" Name=""RecordDateDue"" Grid.Column=""1"" Grid.Row=""3"" />
  2043. <TextBox Style=""{StaticResource trimFormGrid_TB}"" Text=""{Binding Author, Converter={StaticResource trimPropertyConverter}}"" Name=""RecordAuthor"" Grid.Column=""1"" Grid.Row=""4"" xmlns="""" />
  2044. <TextBox Style=""{StaticResource trimFormGrid_TB}"" Text=""{Binding Container, Converter={StaticResource trimPropertyConverter}}"" Name=""RecordContainer"" Grid.Column=""1"" Grid.Row=""5"" xmlns="""" />
  2045. <TextBox Style=""{StaticResource trimFormGrid_TB}"" Text=""{Binding IsEnclosed, Converter={StaticResource trimPropertyConverter}}"" Name=""RecordIsEnclosed"" Grid.Column=""1"" Grid.Row=""6"" xmlns="""" />
  2046. <TextBox Style=""{StaticResource trimFormGrid_TB}"" Text=""{Binding Assignee, Converter={StaticResource trimPropertyConverter}}"" Name=""RecordAssignee"" Grid.Column=""1"" Grid.Row=""7"" xmlns="""" />
  2047. <TextBlock Grid.Column=""0"" Text=""Title (Free Text Part)"" Style=""{StaticResource trimFormGrid_LBL}"" Grid.Row=""0"" xmlns="""" />
  2048. <TextBlock Grid.Column=""0"" Text=""External ID"" Style=""{StaticResource trimFormGrid_LBL}"" Grid.Row=""1"" xmlns="""" />
  2049. <TextBlock Grid.Column=""0"" Text=""Date Created"" Style=""{StaticResource trimFormGrid_LBL}"" Grid.Row=""2"" xmlns="""" />
  2050. <TextBlock Grid.Column=""0"" Text=""Date Due"" Style=""{StaticResource trimFormGrid_LBL}"" Grid.Row=""3"" xmlns="""" />
  2051. <TextBlock Grid.Column=""0"" Text=""Author"" Style=""{StaticResource trimFormGrid_LBL}"" Grid.Row=""4"" xmlns="""" />
  2052. <TextBlock Grid.Column=""0"" Text=""Container"" Style=""{StaticResource trimFormGrid_LBL}"" Grid.Row=""5"" xmlns="""" />
  2053. <TextBlock Grid.Column=""0"" Text=""Enclosed?"" Style=""{StaticResource trimFormGrid_LBL}"" Grid.Row=""6"" xmlns="""" />
  2054. <TextBlock Grid.Column=""0"" Text=""Assignee"" Style=""{StaticResource trimFormGrid_LBL}"" Grid.Row=""7"" xmlns="""" />
  2055. </Grid>";
  2056. XmlDocument document = new XmlDocument();
  2057. document.LoadXml(xaml);
  2058. string json = JsonConvert.SerializeXmlNode(document, Formatting.Indented);
  2059. string expectedJson = @"{
  2060. ""Grid"": {
  2061. ""@xmlns"": ""http://schemas.microsoft.com/winfx/2006/xaml/presentation"",
  2062. ""@xmlns:x"": ""http://schemas.microsoft.com/winfx/2006/xaml"",
  2063. ""@xmlns:toolkit"": ""clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"",
  2064. ""@Style"": ""{StaticResource trimFormGrid}"",
  2065. ""@x:Name"": ""TrimObjectForm"",
  2066. ""Grid.ColumnDefinitions"": {
  2067. ""ColumnDefinition"": [
  2068. {
  2069. ""@Width"": ""63*""
  2070. },
  2071. {
  2072. ""@Width"": ""320*""
  2073. }
  2074. ]
  2075. },
  2076. ""Grid.RowDefinitions"": {
  2077. ""@xmlns"": """",
  2078. ""RowDefinition"": [
  2079. null,
  2080. null,
  2081. null,
  2082. null,
  2083. null,
  2084. null,
  2085. null,
  2086. null
  2087. ]
  2088. },
  2089. ""TextBox"": [
  2090. {
  2091. ""@Style"": ""{StaticResource trimFormGrid_TB}"",
  2092. ""@Text"": ""{Binding TypedTitle, Converter={StaticResource trimPropertyConverter}}"",
  2093. ""@Name"": ""RecordTypedTitle"",
  2094. ""@Grid.Column"": ""1"",
  2095. ""@Grid.Row"": ""0"",
  2096. ""@xmlns"": """"
  2097. },
  2098. {
  2099. ""@Style"": ""{StaticResource trimFormGrid_TB}"",
  2100. ""@Text"": ""{Binding ExternalReference, Converter={StaticResource trimPropertyConverter}}"",
  2101. ""@Name"": ""RecordExternalReference"",
  2102. ""@Grid.Column"": ""1"",
  2103. ""@Grid.Row"": ""1"",
  2104. ""@xmlns"": """"
  2105. },
  2106. {
  2107. ""@Style"": ""{StaticResource trimFormGrid_TB}"",
  2108. ""@Text"": ""{Binding Author, Converter={StaticResource trimPropertyConverter}}"",
  2109. ""@Name"": ""RecordAuthor"",
  2110. ""@Grid.Column"": ""1"",
  2111. ""@Grid.Row"": ""4"",
  2112. ""@xmlns"": """"
  2113. },
  2114. {
  2115. ""@Style"": ""{StaticResource trimFormGrid_TB}"",
  2116. ""@Text"": ""{Binding Container, Converter={StaticResource trimPropertyConverter}}"",
  2117. ""@Name"": ""RecordContainer"",
  2118. ""@Grid.Column"": ""1"",
  2119. ""@Grid.Row"": ""5"",
  2120. ""@xmlns"": """"
  2121. },
  2122. {
  2123. ""@Style"": ""{StaticResource trimFormGrid_TB}"",
  2124. ""@Text"": ""{Binding IsEnclosed, Converter={StaticResource trimPropertyConverter}}"",
  2125. ""@Name"": ""RecordIsEnclosed"",
  2126. ""@Grid.Column"": ""1"",
  2127. ""@Grid.Row"": ""6"",
  2128. ""@xmlns"": """"
  2129. },
  2130. {
  2131. ""@Style"": ""{StaticResource trimFormGrid_TB}"",
  2132. ""@Text"": ""{Binding Assignee, Converter={StaticResource trimPropertyConverter}}"",
  2133. ""@Name"": ""RecordAssignee"",
  2134. ""@Grid.Column"": ""1"",
  2135. ""@Grid.Row"": ""7"",
  2136. ""@xmlns"": """"
  2137. }
  2138. ],
  2139. ""toolkit:DatePicker"": [
  2140. {
  2141. ""@Style"": ""{StaticResource trimFormGrid_DP}"",
  2142. ""@Value"": ""{Binding DateCreated, Converter={StaticResource trimPropertyConverter}}"",
  2143. ""@Name"": ""RecordDateCreated"",
  2144. ""@Grid.Column"": ""1"",
  2145. ""@Grid.Row"": ""2""
  2146. },
  2147. {
  2148. ""@Style"": ""{StaticResource trimFormGrid_DP}"",
  2149. ""@Value"": ""{Binding DateDue, Converter={StaticResource trimPropertyConverter}}"",
  2150. ""@Name"": ""RecordDateDue"",
  2151. ""@Grid.Column"": ""1"",
  2152. ""@Grid.Row"": ""3""
  2153. }
  2154. ],
  2155. ""TextBlock"": [
  2156. {
  2157. ""@Grid.Column"": ""0"",
  2158. ""@Text"": ""Title (Free Text Part)"",
  2159. ""@Style"": ""{StaticResource trimFormGrid_LBL}"",
  2160. ""@Grid.Row"": ""0"",
  2161. ""@xmlns"": """"
  2162. },
  2163. {
  2164. ""@Grid.Column"": ""0"",
  2165. ""@Text"": ""External ID"",
  2166. ""@Style"": ""{StaticResource trimFormGrid_LBL}"",
  2167. ""@Grid.Row"": ""1"",
  2168. ""@xmlns"": """"
  2169. },
  2170. {
  2171. ""@Grid.Column"": ""0"",
  2172. ""@Text"": ""Date Created"",
  2173. ""@Style"": ""{StaticResource trimFormGrid_LBL}"",
  2174. ""@Grid.Row"": ""2"",
  2175. ""@xmlns"": """"
  2176. },
  2177. {
  2178. ""@Grid.Column"": ""0"",
  2179. ""@Text"": ""Date Due"",
  2180. ""@Style"": ""{StaticResource trimFormGrid_LBL}"",
  2181. ""@Grid.Row"": ""3"",
  2182. ""@xmlns"": """"
  2183. },
  2184. {
  2185. ""@Grid.Column"": ""0"",
  2186. ""@Text"": ""Author"",
  2187. ""@Style"": ""{StaticResource trimFormGrid_LBL}"",
  2188. ""@Grid.Row"": ""4"",
  2189. ""@xmlns"": """"
  2190. },
  2191. {
  2192. ""@Grid.Column"": ""0"",
  2193. ""@Text"": ""Container"",
  2194. ""@Style"": ""{StaticResource trimFormGrid_LBL}"",
  2195. ""@Grid.Row"": ""5"",
  2196. ""@xmlns"": """"
  2197. },
  2198. {
  2199. ""@Grid.Column"": ""0"",
  2200. ""@Text"": ""Enclosed?"",
  2201. ""@Style"": ""{StaticResource trimFormGrid_LBL}"",
  2202. ""@Grid.Row"": ""6"",
  2203. ""@xmlns"": """"
  2204. },
  2205. {
  2206. ""@Grid.Column"": ""0"",
  2207. ""@Text"": ""Assignee"",
  2208. ""@Style"": ""{StaticResource trimFormGrid_LBL}"",
  2209. ""@Grid.Row"": ""7"",
  2210. ""@xmlns"": """"
  2211. }
  2212. ]
  2213. }
  2214. }";
  2215. StringAssert.AreEqual(expectedJson, json);
  2216. XmlNode node = JsonConvert.DeserializeXmlNode(json);
  2217. StringWriter sw = new StringWriter();
  2218. XmlWriter writer = XmlWriter.Create(sw, new XmlWriterSettings
  2219. {
  2220. Indent = true,
  2221. OmitXmlDeclaration = true
  2222. });
  2223. node.WriteTo(writer);
  2224. writer.Flush();
  2225. string xaml2 = sw.ToString();
  2226. string expectedXaml = @"<Grid xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" xmlns:toolkit=""clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"" Style=""{StaticResource trimFormGrid}"" x:Name=""TrimObjectForm"">
  2227. <Grid.ColumnDefinitions>
  2228. <ColumnDefinition Width=""63*"" />
  2229. <ColumnDefinition Width=""320*"" />
  2230. </Grid.ColumnDefinitions>
  2231. <Grid.RowDefinitions xmlns="""">
  2232. <RowDefinition />
  2233. <RowDefinition />
  2234. <RowDefinition />
  2235. <RowDefinition />
  2236. <RowDefinition />
  2237. <RowDefinition />
  2238. <RowDefinition />
  2239. <RowDefinition />
  2240. </Grid.RowDefinitions>
  2241. <TextBox Style=""{StaticResource trimFormGrid_TB}"" Text=""{Binding TypedTitle, Converter={StaticResource trimPropertyConverter}}"" Name=""RecordTypedTitle"" Grid.Column=""1"" Grid.Row=""0"" xmlns="""" />
  2242. <TextBox Style=""{StaticResource trimFormGrid_TB}"" Text=""{Binding ExternalReference, Converter={StaticResource trimPropertyConverter}}"" Name=""RecordExternalReference"" Grid.Column=""1"" Grid.Row=""1"" xmlns="""" />
  2243. <TextBox Style=""{StaticResource trimFormGrid_TB}"" Text=""{Binding Author, Converter={StaticResource trimPropertyConverter}}"" Name=""RecordAuthor"" Grid.Column=""1"" Grid.Row=""4"" xmlns="""" />
  2244. <TextBox Style=""{StaticResource trimFormGrid_TB}"" Text=""{Binding Container, Converter={StaticResource trimPropertyConverter}}"" Name=""RecordContainer"" Grid.Column=""1"" Grid.Row=""5"" xmlns="""" />
  2245. <TextBox Style=""{StaticResource trimFormGrid_TB}"" Text=""{Binding IsEnclosed, Converter={StaticResource trimPropertyConverter}}"" Name=""RecordIsEnclosed"" Grid.Column=""1"" Grid.Row=""6"" xmlns="""" />
  2246. <TextBox Style=""{StaticResource trimFormGrid_TB}"" Text=""{Binding Assignee, Converter={StaticResource trimPropertyConverter}}"" Name=""RecordAssignee"" Grid.Column=""1"" Grid.Row=""7"" xmlns="""" />
  2247. <toolkit:DatePicker Style=""{StaticResource trimFormGrid_DP}"" Value=""{Binding DateCreated, Converter={StaticResource trimPropertyConverter}}"" Name=""RecordDateCreated"" Grid.Column=""1"" Grid.Row=""2"" />
  2248. <toolkit:DatePicker Style=""{StaticResource trimFormGrid_DP}"" Value=""{Binding DateDue, Converter={StaticResource trimPropertyConverter}}"" Name=""RecordDateDue"" Grid.Column=""1"" Grid.Row=""3"" />
  2249. <TextBlock Grid.Column=""0"" Text=""Title (Free Text Part)"" Style=""{StaticResource trimFormGrid_LBL}"" Grid.Row=""0"" xmlns="""" />
  2250. <TextBlock Grid.Column=""0"" Text=""External ID"" Style=""{StaticResource trimFormGrid_LBL}"" Grid.Row=""1"" xmlns="""" />
  2251. <TextBlock Grid.Column=""0"" Text=""Date Created"" Style=""{StaticResource trimFormGrid_LBL}"" Grid.Row=""2"" xmlns="""" />
  2252. <TextBlock Grid.Column=""0"" Text=""Date Due"" Style=""{StaticResource trimFormGrid_LBL}"" Grid.Row=""3"" xmlns="""" />
  2253. <TextBlock Grid.Column=""0"" Text=""Author"" Style=""{StaticResource trimFormGrid_LBL}"" Grid.Row=""4"" xmlns="""" />
  2254. <TextBlock Grid.Column=""0"" Text=""Container"" Style=""{StaticResource trimFormGrid_LBL}"" Grid.Row=""5"" xmlns="""" />
  2255. <TextBlock Grid.Column=""0"" Text=""Enclosed?"" Style=""{StaticResource trimFormGrid_LBL}"" Grid.Row=""6"" xmlns="""" />
  2256. <TextBlock Grid.Column=""0"" Text=""Assignee"" Style=""{StaticResource trimFormGrid_LBL}"" Grid.Row=""7"" xmlns="""" />
  2257. </Grid>";
  2258. StringAssert.AreEqual(expectedXaml, xaml2);
  2259. }
  2260. [Test]
  2261. public void DeserializeAttributePropertyNotAtStart()
  2262. {
  2263. string json = @"{""item"": {""@action"": ""update"", ""@itemid"": ""1"", ""elements"": [{""@action"": ""none"", ""@id"": ""2""},{""@action"": ""none"", ""@id"": ""3""}],""@description"": ""temp""}}";
  2264. XmlDocument xmldoc = JsonConvert.DeserializeXmlNode(json);
  2265. Assert.AreEqual(@"<item action=""update"" itemid=""1"" description=""temp""><elements action=""none"" id=""2"" /><elements action=""none"" id=""3"" /></item>", xmldoc.InnerXml);
  2266. }
  2267. #endif
  2268. [Test]
  2269. public void SerializingXmlNamespaceScope()
  2270. {
  2271. var xmlString = @"<root xmlns=""http://www.example.com/ns"">
  2272. <a/>
  2273. <bns:b xmlns:bns=""http://www.example.com/ns""/>
  2274. <c/>
  2275. </root>";
  2276. #if !NET20
  2277. var xml = XElement.Parse(xmlString);
  2278. var json1 = JsonConvert.SerializeObject(xml);
  2279. Assert.AreEqual(@"{""root"":{""@xmlns"":""http://www.example.com/ns"",""a"":null,""bns:b"":{""@xmlns:bns"":""http://www.example.com/ns""},""c"":null}}", json1);
  2280. #endif
  2281. #if !(PORTABLE)
  2282. var xml1 = new XmlDocument();
  2283. xml1.LoadXml(xmlString);
  2284. var json2 = JsonConvert.SerializeObject(xml1);
  2285. Assert.AreEqual(@"{""root"":{""@xmlns"":""http://www.example.com/ns"",""a"":null,""bns:b"":{""@xmlns:bns"":""http://www.example.com/ns""},""c"":null}}", json2);
  2286. #endif
  2287. }
  2288. #if !NET20
  2289. public class NullableXml
  2290. {
  2291. public string Name;
  2292. public XElement notNull;
  2293. public XElement isNull;
  2294. }
  2295. [Test]
  2296. public void SerializeAndDeserializeNullableXml()
  2297. {
  2298. var xml = new NullableXml { Name = "test", notNull = XElement.Parse("<root>test</root>") };
  2299. var json = JsonConvert.SerializeObject(xml);
  2300. var w2 = JsonConvert.DeserializeObject<NullableXml>(json);
  2301. Assert.AreEqual(xml.Name, w2.Name);
  2302. Assert.AreEqual(xml.isNull, w2.isNull);
  2303. Assert.AreEqual(xml.notNull.ToString(), w2.notNull.ToString());
  2304. }
  2305. #endif
  2306. #if !NET20
  2307. [Test]
  2308. public void SerializeAndDeserializeXElementWithNamespaceInChildrenRootDontHaveNameSpace()
  2309. {
  2310. var xmlString = @"<root>
  2311. <b xmlns='http://www.example.com/ns'>Asd</b>
  2312. <c>AAA</c>
  2313. <test>adad</test>
  2314. </root>";
  2315. var xml = XElement.Parse(xmlString);
  2316. var json1 = JsonConvert.SerializeXNode(xml);
  2317. var xmlBack = JsonConvert.DeserializeObject<XElement>(json1);
  2318. var equals = XElement.DeepEquals(xmlBack, xml);
  2319. Assert.IsTrue(equals);
  2320. }
  2321. #endif
  2322. #if !PORTABLE
  2323. [Test]
  2324. public void SerializeAndDeserializeXmlElementWithNamespaceInChildrenRootDontHaveNameSpace()
  2325. {
  2326. var xmlString = @"<root>
  2327. <b xmlns='http://www.example.com/ns'>Asd</b>
  2328. <c>AAA</c>
  2329. <test>adad</test>
  2330. </root>";
  2331. XmlDocument xml = new XmlDocument();
  2332. xml.LoadXml(xmlString);
  2333. var json1 = JsonConvert.SerializeXmlNode(xml);
  2334. var xmlBack = JsonConvert.DeserializeObject<XmlDocument>(json1);
  2335. Assert.AreEqual(@"<root><b xmlns=""http://www.example.com/ns"">Asd</b><c>AAA</c><test>adad</test></root>", xmlBack.OuterXml);
  2336. }
  2337. #if !(NET20 || NET35 || PORTABLE || PORTABLE40) || NETSTANDARD1_1
  2338. [Test]
  2339. public void DeserializeBigInteger()
  2340. {
  2341. var json = "{\"DocumentId\":13779965364495889899 }";
  2342. XmlDocument node = JsonConvert.DeserializeXmlNode(json);
  2343. Assert.AreEqual("<DocumentId>13779965364495889899</DocumentId>", node.OuterXml);
  2344. string json2 = JsonConvert.SerializeXmlNode(node);
  2345. Assert.AreEqual(@"{""DocumentId"":""13779965364495889899""}", json2);
  2346. }
  2347. #endif
  2348. [Test]
  2349. public void DeserializeXmlIncompatibleCharsInPropertyName()
  2350. {
  2351. var json = "{\"%name\":\"value\"}";
  2352. XmlDocument node = JsonConvert.DeserializeXmlNode(json);
  2353. Assert.AreEqual("<_x0025_name>value</_x0025_name>", node.OuterXml);
  2354. string json2 = JsonConvert.SerializeXmlNode(node);
  2355. Assert.AreEqual(json, json2);
  2356. }
  2357. [Test]
  2358. public void RootPropertyError()
  2359. {
  2360. string json = @"{
  2361. ""$id"": ""1"",
  2362. ""AOSLocaleName"": ""en-US"",
  2363. ""AXLanguage"": ""EN-AU"",
  2364. ""Company"": ""AURE"",
  2365. ""CompanyTimeZone"": 8,
  2366. ""CurrencyInfo"": {
  2367. ""$id"": ""2"",
  2368. ""CurrencyCode"": ""AUD"",
  2369. ""Description"": ""Australian Dollar"",
  2370. ""ExchangeRate"": 100.0,
  2371. ""ISOCurrencyCode"": ""AUD"",
  2372. ""Prefix"": """",
  2373. ""Suffix"": """"
  2374. },
  2375. ""IsSysAdmin"": true,
  2376. ""UserId"": ""lamar.miller"",
  2377. ""UserPreferredCalendar"": 0,
  2378. ""UserPreferredTimeZone"": 8
  2379. }";
  2380. ExceptionAssert.Throws<JsonSerializationException>(
  2381. () => JsonConvert.DeserializeXmlNode(json),
  2382. "JSON root object has property '$id' that will be converted to an attribute. A root object cannot have any attribute properties. Consider specifying a DeserializeRootElementName. Path '$id', line 2, position 12.");
  2383. }
  2384. [Test]
  2385. public void SerializeEmptyNodeAndOmitRoot()
  2386. {
  2387. string xmlString = @"<myemptynode />";
  2388. XmlDocument xml = new XmlDocument();
  2389. xml.LoadXml(xmlString);
  2390. string json = JsonConvert.SerializeXmlNode(xml, Formatting.Indented, true);
  2391. Assert.AreEqual("null", json);
  2392. }
  2393. #endif
  2394. #if !NET20
  2395. [Test]
  2396. public void Serialize_XDocument_NoRoot()
  2397. {
  2398. XDocument d = new XDocument();
  2399. string json = JsonConvert.SerializeXNode(d);
  2400. Assert.AreEqual(@"{}", json);
  2401. }
  2402. [Test]
  2403. public void Deserialize_XDocument_NoRoot()
  2404. {
  2405. XDocument d = JsonConvert.DeserializeXNode(@"{}");
  2406. Assert.AreEqual(null, d.Root);
  2407. Assert.AreEqual(null, d.Declaration);
  2408. }
  2409. [Test]
  2410. public void Serialize_XDocument_NoRootWithDeclaration()
  2411. {
  2412. XDocument d = new XDocument();
  2413. d.Declaration = new XDeclaration("Version!", "Encoding!", "Standalone!");
  2414. string json = JsonConvert.SerializeXNode(d);
  2415. Assert.AreEqual(@"{""?xml"":{""@version"":""Version!"",""@encoding"":""Encoding!"",""@standalone"":""Standalone!""}}", json);
  2416. }
  2417. [Test]
  2418. public void Deserialize_XDocument_NoRootWithDeclaration()
  2419. {
  2420. XDocument d = JsonConvert.DeserializeXNode(@"{""?xml"":{""@version"":""Version!"",""@encoding"":""Encoding!"",""@standalone"":""Standalone!""}}");
  2421. Assert.AreEqual(null, d.Root);
  2422. Assert.AreEqual("Version!", d.Declaration.Version);
  2423. Assert.AreEqual("Encoding!", d.Declaration.Encoding);
  2424. Assert.AreEqual("Standalone!", d.Declaration.Standalone);
  2425. }
  2426. [Test]
  2427. public void DateTimeToXml_Unspecified()
  2428. {
  2429. string json = @"{""CreatedDate"": ""2014-01-23T00:00:00""}";
  2430. var dxml = JsonConvert.DeserializeXNode(json, "root");
  2431. Assert.AreEqual("2014-01-23T00:00:00", dxml.Root.Element("CreatedDate").Value);
  2432. Console.WriteLine("DateTimeToXml_Unspecified: " + dxml.Root.Element("CreatedDate").Value);
  2433. }
  2434. [Test]
  2435. public void DateTimeToXml_Utc()
  2436. {
  2437. string json = @"{""CreatedDate"": ""2014-01-23T00:00:00Z""}";
  2438. var dxml = JsonConvert.DeserializeXNode(json, "root");
  2439. Assert.AreEqual("2014-01-23T00:00:00Z", dxml.Root.Element("CreatedDate").Value);
  2440. Console.WriteLine("DateTimeToXml_Utc: " + dxml.Root.Element("CreatedDate").Value);
  2441. }
  2442. [Test]
  2443. public void DateTimeToXml_Local()
  2444. {
  2445. DateTime dt = DateTime.Parse("2014-01-23T00:00:00+01:00");
  2446. string json = @"{""CreatedDate"": ""2014-01-23T00:00:00+01:00""}";
  2447. var dxml = JsonConvert.DeserializeXNode(json, "root");
  2448. Assert.AreEqual(dt.ToString("yyyy-MM-ddTHH:mm:sszzzzzzz", CultureInfo.InvariantCulture), dxml.Root.Element("CreatedDate").Value);
  2449. Console.WriteLine("DateTimeToXml_Local: " + dxml.Root.Element("CreatedDate").Value);
  2450. }
  2451. [Test]
  2452. public void DateTimeToXml_Unspecified_Precision()
  2453. {
  2454. string json = @"{""CreatedDate"": ""2014-01-23T00:00:00.1234567""}";
  2455. var dxml = JsonConvert.DeserializeXNode(json, "root");
  2456. Assert.AreEqual("2014-01-23T00:00:00.1234567", dxml.Root.Element("CreatedDate").Value);
  2457. Console.WriteLine("DateTimeToXml_Unspecified: " + dxml.Root.Element("CreatedDate").Value);
  2458. }
  2459. [Test]
  2460. public void DateTimeToXml_Utc_Precision()
  2461. {
  2462. string json = @"{""CreatedDate"": ""2014-01-23T00:00:00.1234567Z""}";
  2463. var dxml = JsonConvert.DeserializeXNode(json, "root");
  2464. Assert.AreEqual("2014-01-23T00:00:00.1234567Z", dxml.Root.Element("CreatedDate").Value);
  2465. Console.WriteLine("DateTimeToXml_Utc: " + dxml.Root.Element("CreatedDate").Value);
  2466. }
  2467. [Test]
  2468. public void DateTimeToXml_Local_Precision()
  2469. {
  2470. DateTime dt = DateTime.Parse("2014-01-23T00:00:00.1234567+01:00");
  2471. string json = @"{""CreatedDate"": ""2014-01-23T00:00:00.1234567+01:00""}";
  2472. var dxml = JsonConvert.DeserializeXNode(json, "root");
  2473. Assert.AreEqual(dt.ToString("yyyy-MM-ddTHH:mm:ss.FFFFFFFK", CultureInfo.InvariantCulture), dxml.Root.Element("CreatedDate").Value);
  2474. Console.WriteLine("DateTimeToXml_Local: " + dxml.Root.Element("CreatedDate").Value);
  2475. }
  2476. [Test]
  2477. public void SerializeEmptyNodeAndOmitRoot_XElement()
  2478. {
  2479. string xmlString = @"<myemptynode />";
  2480. var xml = XElement.Parse(xmlString);
  2481. string json = JsonConvert.SerializeXNode(xml, Formatting.Indented, true);
  2482. Assert.AreEqual("null", json);
  2483. }
  2484. [Test]
  2485. public void SerializeElementExplicitAttributeNamespace()
  2486. {
  2487. var original = XElement.Parse("<MyElement xmlns=\"http://example.com\" />");
  2488. Assert.AreEqual(@"<MyElement xmlns=""http://example.com"" />", original.ToString());
  2489. var json = JsonConvert.SerializeObject(original);
  2490. Assert.AreEqual(@"{""MyElement"":{""@xmlns"":""http://example.com""}}", json);
  2491. var deserialized = JsonConvert.DeserializeObject<XElement>(json);
  2492. Assert.AreEqual(@"<MyElement xmlns=""http://example.com"" />", deserialized.ToString());
  2493. }
  2494. [Test]
  2495. public void SerializeElementImplicitAttributeNamespace()
  2496. {
  2497. var original = new XElement("{http://example.com}MyElement");
  2498. Assert.AreEqual(@"<MyElement xmlns=""http://example.com"" />", original.ToString());
  2499. var json = JsonConvert.SerializeObject(original);
  2500. Assert.AreEqual(@"{""MyElement"":{""@xmlns"":""http://example.com""}}", json);
  2501. var deserialized = JsonConvert.DeserializeObject<XElement>(json);
  2502. Assert.AreEqual(@"<MyElement xmlns=""http://example.com"" />", deserialized.ToString());
  2503. }
  2504. [Test]
  2505. public void SerializeDocumentExplicitAttributeNamespace()
  2506. {
  2507. var original = XDocument.Parse("<MyElement xmlns=\"http://example.com\" />");
  2508. Assert.AreEqual(@"<MyElement xmlns=""http://example.com"" />", original.ToString());
  2509. var json = JsonConvert.SerializeObject(original);
  2510. Assert.AreEqual(@"{""MyElement"":{""@xmlns"":""http://example.com""}}", json);
  2511. var deserialized = JsonConvert.DeserializeObject<XDocument>(json);
  2512. Assert.AreEqual(@"<MyElement xmlns=""http://example.com"" />", deserialized.ToString());
  2513. }
  2514. [Test]
  2515. public void SerializeDocumentImplicitAttributeNamespace()
  2516. {
  2517. var original = new XDocument(new XElement("{http://example.com}MyElement"));
  2518. Assert.AreEqual(@"<MyElement xmlns=""http://example.com"" />", original.ToString());
  2519. var json = JsonConvert.SerializeObject(original);
  2520. Assert.AreEqual(@"{""MyElement"":{""@xmlns"":""http://example.com""}}", json);
  2521. var deserialized = JsonConvert.DeserializeObject<XDocument>(json);
  2522. Assert.AreEqual(@"<MyElement xmlns=""http://example.com"" />", deserialized.ToString());
  2523. }
  2524. public class Model
  2525. {
  2526. public XElement Document { get; set; }
  2527. }
  2528. [Test]
  2529. public void DeserializeDateInElementText()
  2530. {
  2531. Model model = new Model();
  2532. model.Document = new XElement("Value", new XAttribute("foo", "bar"))
  2533. {
  2534. Value = "2001-01-01T11:11:11"
  2535. };
  2536. var serializer = JsonSerializer.Create(new JsonSerializerSettings
  2537. {
  2538. Converters = new List<JsonConverter>(new[] { new XmlNodeConverter() })
  2539. });
  2540. var json = new StringBuilder(1024);
  2541. using (var stringWriter = new StringWriter(json, CultureInfo.InvariantCulture))
  2542. using (var jsonWriter = new JsonTextWriter(stringWriter))
  2543. {
  2544. jsonWriter.Formatting = Formatting.None;
  2545. serializer.Serialize(jsonWriter, model);
  2546. Assert.AreEqual(@"{""Document"":{""Value"":{""@foo"":""bar"",""#text"":""2001-01-01T11:11:11""}}}", json.ToString());
  2547. }
  2548. using (var stringReader = new StringReader(json.ToString()))
  2549. using (var jsonReader = new JsonTextReader(stringReader))
  2550. {
  2551. var document = (XDocument)serializer.Deserialize(jsonReader, typeof(XDocument));
  2552. StringAssert.AreEqual(@"<Document>
  2553. <Value foo=""bar"">2001-01-01T11:11:11</Value>
  2554. </Document>", document.ToString());
  2555. }
  2556. }
  2557. #endif
  2558. }
  2559. }
  2560. #endif