PageRenderTime 71ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

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

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