PageRenderTime 51ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/Json45r7/Source/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs

https://bitbucket.org/wantstudios/bitbucketclient
C# | 1567 lines | 1255 code | 226 blank | 86 comment | 238 complexity | cb571de279602afc955547196763438d MD5 | raw file
  1. #region License
  2. // Copyright (c) 2007 James Newton-King
  3. //
  4. // Permission is hereby granted, free of charge, to any person
  5. // obtaining a copy of this software and associated documentation
  6. // files (the "Software"), to deal in the Software without
  7. // restriction, including without limitation the rights to use,
  8. // copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the
  10. // Software is furnished to do so, subject to the following
  11. // conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be
  14. // included in all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  18. // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  19. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  20. // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  21. // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  23. // OTHER DEALINGS IN THE SOFTWARE.
  24. #endregion
  25. #if (!(SILVERLIGHT || PORTABLE) || WINDOWS_PHONE)
  26. using System;
  27. using System.Collections.Generic;
  28. using System.Globalization;
  29. using System.Xml;
  30. #if !NET20
  31. using System.Xml.Linq;
  32. #endif
  33. using Newtonsoft.Json.Utilities;
  34. #if NET20
  35. using Newtonsoft.Json.Utilities.LinqBridge;
  36. #else
  37. using System.Linq;
  38. #endif
  39. namespace Newtonsoft.Json.Converters
  40. {
  41. #region XmlNodeWrappers
  42. #if !SILVERLIGHT && !NETFX_CORE
  43. internal class XmlDocumentWrapper : XmlNodeWrapper, IXmlDocument
  44. {
  45. private readonly XmlDocument _document;
  46. public XmlDocumentWrapper(XmlDocument document)
  47. : base(document)
  48. {
  49. _document = document;
  50. }
  51. public IXmlNode CreateComment(string data)
  52. {
  53. return new XmlNodeWrapper(_document.CreateComment(data));
  54. }
  55. public IXmlNode CreateTextNode(string text)
  56. {
  57. return new XmlNodeWrapper(_document.CreateTextNode(text));
  58. }
  59. public IXmlNode CreateCDataSection(string data)
  60. {
  61. return new XmlNodeWrapper(_document.CreateCDataSection(data));
  62. }
  63. public IXmlNode CreateWhitespace(string text)
  64. {
  65. return new XmlNodeWrapper(_document.CreateWhitespace(text));
  66. }
  67. public IXmlNode CreateSignificantWhitespace(string text)
  68. {
  69. return new XmlNodeWrapper(_document.CreateSignificantWhitespace(text));
  70. }
  71. public IXmlNode CreateXmlDeclaration(string version, string encoding, string standalone)
  72. {
  73. return new XmlNodeWrapper(_document.CreateXmlDeclaration(version, encoding, standalone));
  74. }
  75. public IXmlNode CreateProcessingInstruction(string target, string data)
  76. {
  77. return new XmlNodeWrapper(_document.CreateProcessingInstruction(target, data));
  78. }
  79. public IXmlElement CreateElement(string elementName)
  80. {
  81. return new XmlElementWrapper(_document.CreateElement(elementName));
  82. }
  83. public IXmlElement CreateElement(string qualifiedName, string namespaceUri)
  84. {
  85. return new XmlElementWrapper(_document.CreateElement(qualifiedName, namespaceUri));
  86. }
  87. public IXmlNode CreateAttribute(string name, string value)
  88. {
  89. XmlNodeWrapper attribute = new XmlNodeWrapper(_document.CreateAttribute(name));
  90. attribute.Value = value;
  91. return attribute;
  92. }
  93. public IXmlNode CreateAttribute(string qualifiedName, string namespaceUri, string value)
  94. {
  95. XmlNodeWrapper attribute = new XmlNodeWrapper(_document.CreateAttribute(qualifiedName, namespaceUri));
  96. attribute.Value = value;
  97. return attribute;
  98. }
  99. public IXmlElement DocumentElement
  100. {
  101. get
  102. {
  103. if (_document.DocumentElement == null)
  104. return null;
  105. return new XmlElementWrapper(_document.DocumentElement);
  106. }
  107. }
  108. }
  109. internal class XmlElementWrapper : XmlNodeWrapper, IXmlElement
  110. {
  111. private readonly XmlElement _element;
  112. public XmlElementWrapper(XmlElement element)
  113. : base(element)
  114. {
  115. _element = element;
  116. }
  117. public void SetAttributeNode(IXmlNode attribute)
  118. {
  119. XmlNodeWrapper xmlAttributeWrapper = (XmlNodeWrapper)attribute;
  120. _element.SetAttributeNode((XmlAttribute) xmlAttributeWrapper.WrappedNode);
  121. }
  122. public string GetPrefixOfNamespace(string namespaceUri)
  123. {
  124. return _element.GetPrefixOfNamespace(namespaceUri);
  125. }
  126. }
  127. internal class XmlDeclarationWrapper : XmlNodeWrapper, IXmlDeclaration
  128. {
  129. private readonly XmlDeclaration _declaration;
  130. public XmlDeclarationWrapper(XmlDeclaration declaration)
  131. : base(declaration)
  132. {
  133. _declaration = declaration;
  134. }
  135. public string Version
  136. {
  137. get { return _declaration.Version; }
  138. }
  139. public string Encoding
  140. {
  141. get { return _declaration.Encoding; }
  142. set { _declaration.Encoding = value; }
  143. }
  144. public string Standalone
  145. {
  146. get { return _declaration.Standalone; }
  147. set { _declaration.Standalone = value; }
  148. }
  149. }
  150. internal class XmlNodeWrapper : IXmlNode
  151. {
  152. private readonly XmlNode _node;
  153. public XmlNodeWrapper(XmlNode node)
  154. {
  155. _node = node;
  156. }
  157. public object WrappedNode
  158. {
  159. get { return _node; }
  160. }
  161. public XmlNodeType NodeType
  162. {
  163. get { return _node.NodeType; }
  164. }
  165. public string Name
  166. {
  167. get { return _node.Name; }
  168. }
  169. public string LocalName
  170. {
  171. get { return _node.LocalName; }
  172. }
  173. public IList<IXmlNode> ChildNodes
  174. {
  175. get { return _node.ChildNodes.Cast<XmlNode>().Select(n => WrapNode(n)).ToList(); }
  176. }
  177. private IXmlNode WrapNode(XmlNode node)
  178. {
  179. switch (node.NodeType)
  180. {
  181. case XmlNodeType.Element:
  182. return new XmlElementWrapper((XmlElement) node);
  183. case XmlNodeType.XmlDeclaration:
  184. return new XmlDeclarationWrapper((XmlDeclaration) node);
  185. default:
  186. return new XmlNodeWrapper(node);
  187. }
  188. }
  189. public IList<IXmlNode> Attributes
  190. {
  191. get
  192. {
  193. if (_node.Attributes == null)
  194. return null;
  195. return _node.Attributes.Cast<XmlAttribute>().Select(a => WrapNode(a)).ToList();
  196. }
  197. }
  198. public IXmlNode ParentNode
  199. {
  200. get
  201. {
  202. XmlNode node = (_node is XmlAttribute)
  203. ? ((XmlAttribute) _node).OwnerElement
  204. : _node.ParentNode;
  205. if (node == null)
  206. return null;
  207. return WrapNode(node);
  208. }
  209. }
  210. public string Value
  211. {
  212. get { return _node.Value; }
  213. set { _node.Value = value; }
  214. }
  215. public IXmlNode AppendChild(IXmlNode newChild)
  216. {
  217. XmlNodeWrapper xmlNodeWrapper = (XmlNodeWrapper) newChild;
  218. _node.AppendChild(xmlNodeWrapper._node);
  219. return newChild;
  220. }
  221. public string Prefix
  222. {
  223. get { return _node.Prefix; }
  224. }
  225. public string NamespaceUri
  226. {
  227. get { return _node.NamespaceURI; }
  228. }
  229. }
  230. #endif
  231. #endregion
  232. #region Interfaces
  233. internal interface IXmlDocument : IXmlNode
  234. {
  235. IXmlNode CreateComment(string text);
  236. IXmlNode CreateTextNode(string text);
  237. IXmlNode CreateCDataSection(string data);
  238. IXmlNode CreateWhitespace(string text);
  239. IXmlNode CreateSignificantWhitespace(string text);
  240. IXmlNode CreateXmlDeclaration(string version, string encoding, string standalone);
  241. IXmlNode CreateProcessingInstruction(string target, string data);
  242. IXmlElement CreateElement(string elementName);
  243. IXmlElement CreateElement(string qualifiedName, string namespaceUri);
  244. IXmlNode CreateAttribute(string name, string value);
  245. IXmlNode CreateAttribute(string qualifiedName, string namespaceUri, string value);
  246. IXmlElement DocumentElement { get; }
  247. }
  248. internal interface IXmlDeclaration : IXmlNode
  249. {
  250. string Version { get; }
  251. string Encoding { get; set; }
  252. string Standalone { get; set; }
  253. }
  254. internal interface IXmlElement : IXmlNode
  255. {
  256. void SetAttributeNode(IXmlNode attribute);
  257. string GetPrefixOfNamespace(string namespaceUri);
  258. }
  259. internal interface IXmlNode
  260. {
  261. XmlNodeType NodeType { get; }
  262. string LocalName { get; }
  263. IList<IXmlNode> ChildNodes { get; }
  264. IList<IXmlNode> Attributes { get; }
  265. IXmlNode ParentNode { get; }
  266. string Value { get; set; }
  267. IXmlNode AppendChild(IXmlNode newChild);
  268. string NamespaceUri { get; }
  269. object WrappedNode { get; }
  270. }
  271. #endregion
  272. #region XNodeWrappers
  273. #if !NET20
  274. internal class XDeclarationWrapper : XObjectWrapper, IXmlDeclaration
  275. {
  276. internal XDeclaration Declaration { get; private set; }
  277. public XDeclarationWrapper(XDeclaration declaration)
  278. : base(null)
  279. {
  280. Declaration = declaration;
  281. }
  282. public override XmlNodeType NodeType
  283. {
  284. get { return XmlNodeType.XmlDeclaration; }
  285. }
  286. public string Version
  287. {
  288. get { return Declaration.Version; }
  289. }
  290. public string Encoding
  291. {
  292. get { return Declaration.Encoding; }
  293. set { Declaration.Encoding = value; }
  294. }
  295. public string Standalone
  296. {
  297. get { return Declaration.Standalone; }
  298. set { Declaration.Standalone = value; }
  299. }
  300. }
  301. internal class XDocumentWrapper : XContainerWrapper, IXmlDocument
  302. {
  303. private XDocument Document
  304. {
  305. get { return (XDocument)WrappedNode; }
  306. }
  307. public XDocumentWrapper(XDocument document)
  308. : base(document)
  309. {
  310. }
  311. public override IList<IXmlNode> ChildNodes
  312. {
  313. get
  314. {
  315. IList<IXmlNode> childNodes = base.ChildNodes;
  316. if (Document.Declaration != null)
  317. childNodes.Insert(0, new XDeclarationWrapper(Document.Declaration));
  318. return childNodes;
  319. }
  320. }
  321. public IXmlNode CreateComment(string text)
  322. {
  323. return new XObjectWrapper(new XComment(text));
  324. }
  325. public IXmlNode CreateTextNode(string text)
  326. {
  327. return new XObjectWrapper(new XText(text));
  328. }
  329. public IXmlNode CreateCDataSection(string data)
  330. {
  331. return new XObjectWrapper(new XCData(data));
  332. }
  333. public IXmlNode CreateWhitespace(string text)
  334. {
  335. return new XObjectWrapper(new XText(text));
  336. }
  337. public IXmlNode CreateSignificantWhitespace(string text)
  338. {
  339. return new XObjectWrapper(new XText(text));
  340. }
  341. public IXmlNode CreateXmlDeclaration(string version, string encoding, string standalone)
  342. {
  343. return new XDeclarationWrapper(new XDeclaration(version, encoding, standalone));
  344. }
  345. public IXmlNode CreateProcessingInstruction(string target, string data)
  346. {
  347. return new XProcessingInstructionWrapper(new XProcessingInstruction(target, data));
  348. }
  349. public IXmlElement CreateElement(string elementName)
  350. {
  351. return new XElementWrapper(new XElement(elementName));
  352. }
  353. public IXmlElement CreateElement(string qualifiedName, string namespaceUri)
  354. {
  355. string localName = MiscellaneousUtils.GetLocalName(qualifiedName);
  356. return new XElementWrapper(new XElement(XName.Get(localName, namespaceUri)));
  357. }
  358. public IXmlNode CreateAttribute(string name, string value)
  359. {
  360. return new XAttributeWrapper(new XAttribute(name, value));
  361. }
  362. public IXmlNode CreateAttribute(string qualifiedName, string namespaceUri, string value)
  363. {
  364. string localName = MiscellaneousUtils.GetLocalName(qualifiedName);
  365. return new XAttributeWrapper(new XAttribute(XName.Get(localName, namespaceUri), value));
  366. }
  367. public IXmlElement DocumentElement
  368. {
  369. get
  370. {
  371. if (Document.Root == null)
  372. return null;
  373. return new XElementWrapper(Document.Root);
  374. }
  375. }
  376. public override IXmlNode AppendChild(IXmlNode newChild)
  377. {
  378. XDeclarationWrapper declarationWrapper = newChild as XDeclarationWrapper;
  379. if (declarationWrapper != null)
  380. {
  381. Document.Declaration = declarationWrapper.Declaration;
  382. return declarationWrapper;
  383. }
  384. else
  385. {
  386. return base.AppendChild(newChild);
  387. }
  388. }
  389. }
  390. internal class XTextWrapper : XObjectWrapper
  391. {
  392. private XText Text
  393. {
  394. get { return (XText)WrappedNode; }
  395. }
  396. public XTextWrapper(XText text)
  397. : base(text)
  398. {
  399. }
  400. public override string Value
  401. {
  402. get { return Text.Value; }
  403. set { Text.Value = value; }
  404. }
  405. public override IXmlNode ParentNode
  406. {
  407. get
  408. {
  409. if (Text.Parent == null)
  410. return null;
  411. return XContainerWrapper.WrapNode(Text.Parent);
  412. }
  413. }
  414. }
  415. internal class XCommentWrapper : XObjectWrapper
  416. {
  417. private XComment Text
  418. {
  419. get { return (XComment)WrappedNode; }
  420. }
  421. public XCommentWrapper(XComment text)
  422. : base(text)
  423. {
  424. }
  425. public override string Value
  426. {
  427. get { return Text.Value; }
  428. set { Text.Value = value; }
  429. }
  430. public override IXmlNode ParentNode
  431. {
  432. get
  433. {
  434. if (Text.Parent == null)
  435. return null;
  436. return XContainerWrapper.WrapNode(Text.Parent);
  437. }
  438. }
  439. }
  440. internal class XProcessingInstructionWrapper : XObjectWrapper
  441. {
  442. private XProcessingInstruction ProcessingInstruction
  443. {
  444. get { return (XProcessingInstruction)WrappedNode; }
  445. }
  446. public XProcessingInstructionWrapper(XProcessingInstruction processingInstruction)
  447. : base(processingInstruction)
  448. {
  449. }
  450. public override string LocalName
  451. {
  452. get { return ProcessingInstruction.Target; }
  453. }
  454. public override string Value
  455. {
  456. get { return ProcessingInstruction.Data; }
  457. set { ProcessingInstruction.Data = value; }
  458. }
  459. }
  460. internal class XContainerWrapper : XObjectWrapper
  461. {
  462. private XContainer Container
  463. {
  464. get { return (XContainer)WrappedNode; }
  465. }
  466. public XContainerWrapper(XContainer container)
  467. : base(container)
  468. {
  469. }
  470. public override IList<IXmlNode> ChildNodes
  471. {
  472. get { return Container.Nodes().Select(n => WrapNode(n)).ToList(); }
  473. }
  474. public override IXmlNode ParentNode
  475. {
  476. get
  477. {
  478. if (Container.Parent == null)
  479. return null;
  480. return WrapNode(Container.Parent);
  481. }
  482. }
  483. internal static IXmlNode WrapNode(XObject node)
  484. {
  485. if (node is XDocument)
  486. return new XDocumentWrapper((XDocument)node);
  487. else if (node is XElement)
  488. return new XElementWrapper((XElement)node);
  489. else if (node is XContainer)
  490. return new XContainerWrapper((XContainer)node);
  491. else if (node is XProcessingInstruction)
  492. return new XProcessingInstructionWrapper((XProcessingInstruction)node);
  493. else if (node is XText)
  494. return new XTextWrapper((XText)node);
  495. else if (node is XComment)
  496. return new XCommentWrapper((XComment)node);
  497. else if (node is XAttribute)
  498. return new XAttributeWrapper((XAttribute) node);
  499. else
  500. return new XObjectWrapper(node);
  501. }
  502. public override IXmlNode AppendChild(IXmlNode newChild)
  503. {
  504. Container.Add(newChild.WrappedNode);
  505. return newChild;
  506. }
  507. }
  508. internal class XObjectWrapper : IXmlNode
  509. {
  510. private readonly XObject _xmlObject;
  511. public XObjectWrapper(XObject xmlObject)
  512. {
  513. _xmlObject = xmlObject;
  514. }
  515. public object WrappedNode
  516. {
  517. get { return _xmlObject; }
  518. }
  519. public virtual XmlNodeType NodeType
  520. {
  521. get { return _xmlObject.NodeType; }
  522. }
  523. public virtual string LocalName
  524. {
  525. get { return null; }
  526. }
  527. public virtual IList<IXmlNode> ChildNodes
  528. {
  529. get { return new List<IXmlNode>(); }
  530. }
  531. public virtual IList<IXmlNode> Attributes
  532. {
  533. get { return null; }
  534. }
  535. public virtual IXmlNode ParentNode
  536. {
  537. get { return null; }
  538. }
  539. public virtual string Value
  540. {
  541. get { return null; }
  542. set { throw new InvalidOperationException(); }
  543. }
  544. public virtual IXmlNode AppendChild(IXmlNode newChild)
  545. {
  546. throw new InvalidOperationException();
  547. }
  548. public virtual string NamespaceUri
  549. {
  550. get { return null; }
  551. }
  552. }
  553. internal class XAttributeWrapper : XObjectWrapper
  554. {
  555. private XAttribute Attribute
  556. {
  557. get { return (XAttribute)WrappedNode; }
  558. }
  559. public XAttributeWrapper(XAttribute attribute)
  560. : base(attribute)
  561. {
  562. }
  563. public override string Value
  564. {
  565. get { return Attribute.Value; }
  566. set { Attribute.Value = value; }
  567. }
  568. public override string LocalName
  569. {
  570. get { return Attribute.Name.LocalName; }
  571. }
  572. public override string NamespaceUri
  573. {
  574. get { return Attribute.Name.NamespaceName; }
  575. }
  576. public override IXmlNode ParentNode
  577. {
  578. get
  579. {
  580. if (Attribute.Parent == null)
  581. return null;
  582. return XContainerWrapper.WrapNode(Attribute.Parent);
  583. }
  584. }
  585. }
  586. internal class XElementWrapper : XContainerWrapper, IXmlElement
  587. {
  588. private XElement Element
  589. {
  590. get { return (XElement) WrappedNode; }
  591. }
  592. public XElementWrapper(XElement element)
  593. : base(element)
  594. {
  595. }
  596. public void SetAttributeNode(IXmlNode attribute)
  597. {
  598. XObjectWrapper wrapper = (XObjectWrapper)attribute;
  599. Element.Add(wrapper.WrappedNode);
  600. }
  601. public override IList<IXmlNode> Attributes
  602. {
  603. get { return Element.Attributes().Select(a => new XAttributeWrapper(a)).Cast<IXmlNode>().ToList(); }
  604. }
  605. public override string Value
  606. {
  607. get { return Element.Value; }
  608. set { Element.Value = value; }
  609. }
  610. public override string LocalName
  611. {
  612. get { return Element.Name.LocalName; }
  613. }
  614. public override string NamespaceUri
  615. {
  616. get { return Element.Name.NamespaceName; }
  617. }
  618. public string GetPrefixOfNamespace(string namespaceUri)
  619. {
  620. return Element.GetPrefixOfNamespace(namespaceUri);
  621. }
  622. }
  623. #endif
  624. #endregion
  625. /// <summary>
  626. /// Converts XML to and from JSON.
  627. /// </summary>
  628. public class XmlNodeConverter : JsonConverter
  629. {
  630. private const string TextName = "#text";
  631. private const string CommentName = "#comment";
  632. private const string CDataName = "#cdata-section";
  633. private const string WhitespaceName = "#whitespace";
  634. private const string SignificantWhitespaceName = "#significant-whitespace";
  635. private const string DeclarationName = "?xml";
  636. private const string JsonNamespaceUri = "http://james.newtonking.com/projects/json";
  637. /// <summary>
  638. /// Gets or sets the name of the root element to insert when deserializing to XML if the JSON structure has produces multiple root elements.
  639. /// </summary>
  640. /// <value>The name of the deserialize root element.</value>
  641. public string DeserializeRootElementName { get; set; }
  642. /// <summary>
  643. /// Gets or sets a flag to indicate whether to write the Json.NET array attribute.
  644. /// This attribute helps preserve arrays when converting the written XML back to JSON.
  645. /// </summary>
  646. /// <value><c>true</c> if the array attibute is written to the XML; otherwise, <c>false</c>.</value>
  647. public bool WriteArrayAttribute { get; set; }
  648. /// <summary>
  649. /// Gets or sets a value indicating whether to write the root JSON object.
  650. /// </summary>
  651. /// <value><c>true</c> if the JSON root object is omitted; otherwise, <c>false</c>.</value>
  652. public bool OmitRootObject { get; set; }
  653. #region Writing
  654. /// <summary>
  655. /// Writes the JSON representation of the object.
  656. /// </summary>
  657. /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
  658. /// <param name="serializer">The calling serializer.</param>
  659. /// <param name="value">The value.</param>
  660. public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
  661. {
  662. IXmlNode node = WrapXml(value);
  663. XmlNamespaceManager manager = new XmlNamespaceManager(new NameTable());
  664. PushParentNamespaces(node, manager);
  665. if (!OmitRootObject)
  666. writer.WriteStartObject();
  667. SerializeNode(writer, node, manager, !OmitRootObject);
  668. if (!OmitRootObject)
  669. writer.WriteEndObject();
  670. }
  671. private IXmlNode WrapXml(object value)
  672. {
  673. #if !NET20
  674. if (value is XObject)
  675. return XContainerWrapper.WrapNode((XObject)value);
  676. #endif
  677. #if !(SILVERLIGHT || NETFX_CORE)
  678. if (value is XmlNode)
  679. return new XmlNodeWrapper((XmlNode)value);
  680. #endif
  681. throw new ArgumentException("Value must be an XML object.", "value");
  682. }
  683. private void PushParentNamespaces(IXmlNode node, XmlNamespaceManager manager)
  684. {
  685. List<IXmlNode> parentElements = null;
  686. IXmlNode parent = node;
  687. while ((parent = parent.ParentNode) != null)
  688. {
  689. if (parent.NodeType == XmlNodeType.Element)
  690. {
  691. if (parentElements == null)
  692. parentElements = new List<IXmlNode>();
  693. parentElements.Add(parent);
  694. }
  695. }
  696. if (parentElements != null)
  697. {
  698. parentElements.Reverse();
  699. foreach (IXmlNode parentElement in parentElements)
  700. {
  701. manager.PushScope();
  702. foreach (IXmlNode attribute in parentElement.Attributes)
  703. {
  704. if (attribute.NamespaceUri == "http://www.w3.org/2000/xmlns/" && attribute.LocalName != "xmlns")
  705. manager.AddNamespace(attribute.LocalName, attribute.Value);
  706. }
  707. }
  708. }
  709. }
  710. private string ResolveFullName(IXmlNode node, XmlNamespaceManager manager)
  711. {
  712. string prefix = (node.NamespaceUri == null || (node.LocalName == "xmlns" && node.NamespaceUri == "http://www.w3.org/2000/xmlns/"))
  713. ? null
  714. : manager.LookupPrefix(node.NamespaceUri);
  715. if (!string.IsNullOrEmpty(prefix))
  716. return prefix + ":" + node.LocalName;
  717. else
  718. return node.LocalName;
  719. }
  720. private string GetPropertyName(IXmlNode node, XmlNamespaceManager manager)
  721. {
  722. switch (node.NodeType)
  723. {
  724. case XmlNodeType.Attribute:
  725. if (node.NamespaceUri == JsonNamespaceUri)
  726. return "$" + node.LocalName;
  727. else
  728. return "@" + ResolveFullName(node, manager);
  729. case XmlNodeType.CDATA:
  730. return CDataName;
  731. case XmlNodeType.Comment:
  732. return CommentName;
  733. case XmlNodeType.Element:
  734. return ResolveFullName(node, manager);
  735. case XmlNodeType.ProcessingInstruction:
  736. return "?" + ResolveFullName(node, manager);
  737. case XmlNodeType.XmlDeclaration:
  738. return DeclarationName;
  739. case XmlNodeType.SignificantWhitespace:
  740. return SignificantWhitespaceName;
  741. case XmlNodeType.Text:
  742. return TextName;
  743. case XmlNodeType.Whitespace:
  744. return WhitespaceName;
  745. default:
  746. throw new JsonSerializationException("Unexpected XmlNodeType when getting node name: " + node.NodeType);
  747. }
  748. }
  749. private bool IsArray(IXmlNode node)
  750. {
  751. IXmlNode jsonArrayAttribute = (node.Attributes != null)
  752. ? node.Attributes.SingleOrDefault(a => a.LocalName == "Array" && a.NamespaceUri == JsonNamespaceUri)
  753. : null;
  754. return (jsonArrayAttribute != null && XmlConvert.ToBoolean(jsonArrayAttribute.Value));
  755. }
  756. private void SerializeGroupedNodes(JsonWriter writer, IXmlNode node, XmlNamespaceManager manager, bool writePropertyName)
  757. {
  758. // group nodes together by name
  759. Dictionary<string, List<IXmlNode>> nodesGroupedByName = new Dictionary<string, List<IXmlNode>>();
  760. for (int i = 0; i < node.ChildNodes.Count; i++)
  761. {
  762. IXmlNode childNode = node.ChildNodes[i];
  763. string nodeName = GetPropertyName(childNode, manager);
  764. List<IXmlNode> nodes;
  765. if (!nodesGroupedByName.TryGetValue(nodeName, out nodes))
  766. {
  767. nodes = new List<IXmlNode>();
  768. nodesGroupedByName.Add(nodeName, nodes);
  769. }
  770. nodes.Add(childNode);
  771. }
  772. // loop through grouped nodes. write single name instances as normal,
  773. // write multiple names together in an array
  774. foreach (KeyValuePair<string, List<IXmlNode>> nodeNameGroup in nodesGroupedByName)
  775. {
  776. List<IXmlNode> groupedNodes = nodeNameGroup.Value;
  777. bool writeArray;
  778. if (groupedNodes.Count == 1)
  779. {
  780. writeArray = IsArray(groupedNodes[0]);
  781. }
  782. else
  783. {
  784. writeArray = true;
  785. }
  786. if (!writeArray)
  787. {
  788. SerializeNode(writer, groupedNodes[0], manager, writePropertyName);
  789. }
  790. else
  791. {
  792. string elementNames = nodeNameGroup.Key;
  793. if (writePropertyName)
  794. writer.WritePropertyName(elementNames);
  795. writer.WriteStartArray();
  796. for (int i = 0; i < groupedNodes.Count; i++)
  797. {
  798. SerializeNode(writer, groupedNodes[i], manager, false);
  799. }
  800. writer.WriteEndArray();
  801. }
  802. }
  803. }
  804. private void SerializeNode(JsonWriter writer, IXmlNode node, XmlNamespaceManager manager, bool writePropertyName)
  805. {
  806. switch (node.NodeType)
  807. {
  808. case XmlNodeType.Document:
  809. case XmlNodeType.DocumentFragment:
  810. SerializeGroupedNodes(writer, node, manager, writePropertyName);
  811. break;
  812. case XmlNodeType.Element:
  813. if (IsArray(node) && node.ChildNodes.All(n => n.LocalName == node.LocalName) && node.ChildNodes.Count > 0)
  814. {
  815. SerializeGroupedNodes(writer, node, manager, false);
  816. }
  817. else
  818. {
  819. foreach (IXmlNode attribute in node.Attributes)
  820. {
  821. if (attribute.NamespaceUri == "http://www.w3.org/2000/xmlns/")
  822. {
  823. string prefix = (attribute.LocalName != "xmlns")
  824. ? attribute.LocalName
  825. : string.Empty;
  826. manager.AddNamespace(prefix, attribute.Value);
  827. }
  828. }
  829. if (writePropertyName)
  830. writer.WritePropertyName(GetPropertyName(node, manager));
  831. if (!ValueAttributes(node.Attributes).Any() && node.ChildNodes.Count == 1
  832. && node.ChildNodes[0].NodeType == XmlNodeType.Text)
  833. {
  834. // write elements with a single text child as a name value pair
  835. writer.WriteValue(node.ChildNodes[0].Value);
  836. }
  837. else if (node.ChildNodes.Count == 0 && CollectionUtils.IsNullOrEmpty(node.Attributes))
  838. {
  839. // empty element
  840. writer.WriteNull();
  841. }
  842. else
  843. {
  844. writer.WriteStartObject();
  845. for (int i = 0; i < node.Attributes.Count; i++)
  846. {
  847. SerializeNode(writer, node.Attributes[i], manager, true);
  848. }
  849. SerializeGroupedNodes(writer, node, manager, true);
  850. writer.WriteEndObject();
  851. }
  852. }
  853. break;
  854. case XmlNodeType.Comment:
  855. if (writePropertyName)
  856. writer.WriteComment(node.Value);
  857. break;
  858. case XmlNodeType.Attribute:
  859. case XmlNodeType.Text:
  860. case XmlNodeType.CDATA:
  861. case XmlNodeType.ProcessingInstruction:
  862. case XmlNodeType.Whitespace:
  863. case XmlNodeType.SignificantWhitespace:
  864. if (node.NamespaceUri == "http://www.w3.org/2000/xmlns/" && node.Value == JsonNamespaceUri)
  865. return;
  866. if (node.NamespaceUri == JsonNamespaceUri)
  867. {
  868. if (node.LocalName == "Array")
  869. return;
  870. }
  871. if (writePropertyName)
  872. writer.WritePropertyName(GetPropertyName(node, manager));
  873. writer.WriteValue(node.Value);
  874. break;
  875. case XmlNodeType.XmlDeclaration:
  876. IXmlDeclaration declaration = (IXmlDeclaration)node;
  877. writer.WritePropertyName(GetPropertyName(node, manager));
  878. writer.WriteStartObject();
  879. if (!string.IsNullOrEmpty(declaration.Version))
  880. {
  881. writer.WritePropertyName("@version");
  882. writer.WriteValue(declaration.Version);
  883. }
  884. if (!string.IsNullOrEmpty(declaration.Encoding))
  885. {
  886. writer.WritePropertyName("@encoding");
  887. writer.WriteValue(declaration.Encoding);
  888. }
  889. if (!string.IsNullOrEmpty(declaration.Standalone))
  890. {
  891. writer.WritePropertyName("@standalone");
  892. writer.WriteValue(declaration.Standalone);
  893. }
  894. writer.WriteEndObject();
  895. break;
  896. default:
  897. throw new JsonSerializationException("Unexpected XmlNodeType when serializing nodes: " + node.NodeType);
  898. }
  899. }
  900. #endregion
  901. #region Reading
  902. /// <summary>
  903. /// Reads the JSON representation of the object.
  904. /// </summary>
  905. /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
  906. /// <param name="objectType">Type of the object.</param>
  907. /// <param name="existingValue">The existing value of object being read.</param>
  908. /// <param name="serializer">The calling serializer.</param>
  909. /// <returns>The object value.</returns>
  910. public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
  911. {
  912. XmlNamespaceManager manager = new XmlNamespaceManager(new NameTable());
  913. IXmlDocument document = null;
  914. IXmlNode rootNode = null;
  915. #if !NET20
  916. if (typeof(XObject).IsAssignableFrom(objectType))
  917. {
  918. if (objectType != typeof (XDocument) && objectType != typeof (XElement))
  919. throw new JsonSerializationException("XmlNodeConverter only supports deserializing XDocument or XElement.");
  920. XDocument d = new XDocument();
  921. document = new XDocumentWrapper(d);
  922. rootNode = document;
  923. }
  924. #endif
  925. #if !(SILVERLIGHT || NETFX_CORE)
  926. if (typeof(XmlNode).IsAssignableFrom(objectType))
  927. {
  928. if (objectType != typeof (XmlDocument))
  929. throw new JsonSerializationException("XmlNodeConverter only supports deserializing XmlDocuments");
  930. XmlDocument d = new XmlDocument();
  931. document = new XmlDocumentWrapper(d);
  932. rootNode = document;
  933. }
  934. #endif
  935. if (document == null || rootNode == null)
  936. throw new JsonSerializationException("Unexpected type when converting XML: " + objectType);
  937. if (reader.TokenType != JsonToken.StartObject)
  938. throw new JsonSerializationException("XmlNodeConverter can only convert JSON that begins with an object.");
  939. if (!string.IsNullOrEmpty(DeserializeRootElementName))
  940. {
  941. //rootNode = document.CreateElement(DeserializeRootElementName);
  942. //document.AppendChild(rootNode);
  943. ReadElement(reader, document, rootNode, DeserializeRootElementName, manager);
  944. }
  945. else
  946. {
  947. reader.Read();
  948. DeserializeNode(reader, document, manager, rootNode);
  949. }
  950. #if !NET20
  951. if (objectType == typeof(XElement))
  952. {
  953. XElement element = (XElement)document.DocumentElement.WrappedNode;
  954. element.Remove();
  955. return element;
  956. }
  957. #endif
  958. return document.WrappedNode;
  959. }
  960. private void DeserializeValue(JsonReader reader, IXmlDocument document, XmlNamespaceManager manager, string propertyName, IXmlNode currentNode)
  961. {
  962. switch (propertyName)
  963. {
  964. case TextName:
  965. currentNode.AppendChild(document.CreateTextNode(reader.Value.ToString()));
  966. break;
  967. case CDataName:
  968. currentNode.AppendChild(document.CreateCDataSection(reader.Value.ToString()));
  969. break;
  970. case WhitespaceName:
  971. currentNode.AppendChild(document.CreateWhitespace(reader.Value.ToString()));
  972. break;
  973. case SignificantWhitespaceName:
  974. currentNode.AppendChild(document.CreateSignificantWhitespace(reader.Value.ToString()));
  975. break;
  976. default:
  977. // processing instructions and the xml declaration start with ?
  978. if (!string.IsNullOrEmpty(propertyName) && propertyName[0] == '?')
  979. {
  980. CreateInstruction(reader, document, currentNode, propertyName);
  981. }
  982. else
  983. {
  984. if (reader.TokenType == JsonToken.StartArray)
  985. {
  986. // handle nested arrays
  987. ReadArrayElements(reader, document, propertyName, currentNode, manager);
  988. return;
  989. }
  990. // have to wait until attributes have been parsed before creating element
  991. // attributes may contain namespace info used by the element
  992. ReadElement(reader, document, currentNode, propertyName, manager);
  993. }
  994. break;
  995. }
  996. }
  997. private void ReadElement(JsonReader reader, IXmlDocument document, IXmlNode currentNode, string propertyName, XmlNamespaceManager manager)
  998. {
  999. if (string.IsNullOrEmpty(propertyName))
  1000. throw new JsonSerializationException("XmlNodeConverter cannot convert JSON with an empty property name to XML.");
  1001. Dictionary<string, string> attributeNameValues = ReadAttributeElements(reader, manager);
  1002. string elementPrefix = MiscellaneousUtils.GetPrefix(propertyName);
  1003. if (propertyName.StartsWith("@"))
  1004. {
  1005. var attributeName = propertyName.Substring(1);
  1006. var attributeValue = reader.Value.ToString();
  1007. var attributePrefix = MiscellaneousUtils.GetPrefix(attributeName);
  1008. var attribute = (!string.IsNullOrEmpty(attributePrefix))
  1009. ? document.CreateAttribute(attributeName, manager.LookupNamespace(attributePrefix), attributeValue)
  1010. : document.CreateAttribute(attributeName, attributeValue);
  1011. ((IXmlElement)currentNode).SetAttributeNode(attribute);
  1012. }
  1013. else
  1014. {
  1015. IXmlElement element = CreateElement(propertyName, document, elementPrefix, manager);
  1016. currentNode.AppendChild(element);
  1017. // add attributes to newly created element
  1018. foreach (KeyValuePair<string, string> nameValue in attributeNameValues)
  1019. {
  1020. string attributePrefix = MiscellaneousUtils.GetPrefix(nameValue.Key);
  1021. IXmlNode attribute = (!string.IsNullOrEmpty(attributePrefix))
  1022. ? document.CreateAttribute(nameValue.Key, manager.LookupNamespace(attributePrefix), nameValue.Value)
  1023. : document.CreateAttribute(nameValue.Key, nameValue.Value);
  1024. element.SetAttributeNode(attribute);
  1025. }
  1026. if (reader.TokenType == JsonToken.String
  1027. || reader.TokenType == JsonToken.Integer
  1028. || reader.TokenType == JsonToken.Float
  1029. || reader.TokenType == JsonToken.Boolean
  1030. || reader.TokenType == JsonToken.Date)
  1031. {
  1032. element.AppendChild(document.CreateTextNode(ConvertTokenToXmlValue(reader)));
  1033. }
  1034. else if (reader.TokenType == JsonToken.Null)
  1035. {
  1036. // empty element. do nothing
  1037. }
  1038. else
  1039. {
  1040. // finished element will have no children to deserialize
  1041. if (reader.TokenType != JsonToken.EndObject)
  1042. {
  1043. manager.PushScope();
  1044. DeserializeNode(reader, document, manager, element);
  1045. manager.PopScope();
  1046. }
  1047. }
  1048. }
  1049. }
  1050. private string ConvertTokenToXmlValue(JsonReader reader)
  1051. {
  1052. if (reader.TokenType == JsonToken.String)
  1053. {
  1054. return reader.Value.ToString();
  1055. }
  1056. else if (reader.TokenType == JsonToken.Integer)
  1057. {
  1058. return XmlConvert.ToString(Convert.ToInt64(reader.Value, CultureInfo.InvariantCulture));
  1059. }
  1060. else if (reader.TokenType == JsonToken.Float)
  1061. {
  1062. return XmlConvert.ToString(Convert.ToDouble(reader.Value, CultureInfo.InvariantCulture));
  1063. }
  1064. else if (reader.TokenType == JsonToken.Boolean)
  1065. {
  1066. return XmlConvert.ToString(Convert.ToBoolean(reader.Value, CultureInfo.InvariantCulture));
  1067. }
  1068. else if (reader.TokenType == JsonToken.Date)
  1069. {
  1070. DateTime d = Convert.ToDateTime(reader.Value, CultureInfo.InvariantCulture);
  1071. #if !NETFX_CORE
  1072. return XmlConvert.ToString(d, DateTimeUtils.ToSerializationMode(d.Kind));
  1073. #else
  1074. return XmlConvert.ToString(d);
  1075. #endif
  1076. }
  1077. else if (reader.TokenType == JsonToken.Null)
  1078. {
  1079. return null;
  1080. }
  1081. else
  1082. {
  1083. throw JsonSerializationException.Create(reader, "Cannot get an XML string value from token type '{0}'.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
  1084. }
  1085. }
  1086. private void ReadArrayElements(JsonReader reader, IXmlDocument document, string propertyName, IXmlNode currentNode, XmlNamespaceManager manager)
  1087. {
  1088. string elementPrefix = MiscellaneousUtils.GetPrefix(propertyName);
  1089. IXmlElement nestedArrayElement = CreateElement(propertyName, document, elementPrefix, manager);
  1090. currentNode.AppendChild(nestedArrayElement);
  1091. int count = 0;
  1092. while (reader.Read() && reader.TokenType != JsonToken.EndArray)
  1093. {
  1094. DeserializeValue(reader, document, manager, propertyName, nestedArrayElement);
  1095. count++;
  1096. }
  1097. if (WriteArrayAttribute)
  1098. {
  1099. AddJsonArrayAttribute(nestedArrayElement, document);
  1100. }
  1101. if (count == 1 && WriteArrayAttribute)
  1102. {
  1103. IXmlElement arrayElement = nestedArrayElement.ChildNodes.CastValid<IXmlElement>().Single(n => n.LocalName == propertyName);
  1104. AddJsonArrayAttribute(arrayElement, document);
  1105. }
  1106. }
  1107. private void AddJsonArrayAttribute(IXmlElement element, IXmlDocument document)
  1108. {
  1109. element.SetAttributeNode(document.CreateAttribute("json:Array", JsonNamespaceUri, "true"));
  1110. #if !NET20
  1111. // linq to xml doesn't automatically include prefixes via the namespace manager
  1112. if (element is XElementWrapper)
  1113. {
  1114. if (element.GetPrefixOfNamespace(JsonNamespaceUri) == null)
  1115. {
  1116. element.SetAttributeNode(document.CreateAttribute("xmlns:json", "http://www.w3.org/2000/xmlns/", JsonNamespaceUri));
  1117. }
  1118. }
  1119. #endif
  1120. }
  1121. private Dictionary<string, string> ReadAttributeElements(JsonReader reader, XmlNamespaceManager manager)
  1122. {
  1123. Dictionary<string, string> attributeNameValues = new Dictionary<string, string>();
  1124. bool finishedAttributes = false;
  1125. bool finishedElement = false;
  1126. // a string token means the element only has a single text child
  1127. if (reader.TokenType != JsonToken.String
  1128. && reader.TokenType != JsonToken.Null
  1129. && reader.TokenType != JsonToken.Boolean
  1130. && reader.TokenType != JsonToken.Integer
  1131. && reader.TokenType != JsonToken.Float
  1132. && reader.TokenType != JsonToken.Date
  1133. && reader.TokenType != JsonToken.StartConstructor)
  1134. {
  1135. // read properties until first non-attribute is encountered
  1136. while (!finishedAttributes && !finishedElement && reader.Read())
  1137. {
  1138. switch (reader.TokenType)
  1139. {
  1140. case JsonToken.PropertyName:
  1141. string attributeName = reader.Value.ToString();
  1142. if (!string.IsNullOrEmpty(attributeName))
  1143. {
  1144. char firstChar = attributeName[0];
  1145. string attributeValue;
  1146. switch (firstChar)
  1147. {
  1148. case '@':
  1149. attributeName = attributeName.Substring(1);
  1150. reader.Read();
  1151. attributeValue = ConvertTokenToXmlValue(reader);
  1152. attributeNameValues.Add(attributeName, attributeValue);
  1153. string namespacePrefix;
  1154. if (IsNamespaceAttribute(attributeName, out namespacePrefix))
  1155. {
  1156. manager.AddNamespace(namespacePrefix, attributeValue);
  1157. }
  1158. break;
  1159. case '$':
  1160. attributeName = attributeName.Substring(1);
  1161. reader.Read();
  1162. attributeValue = reader.Value.ToString();
  1163. // check that JsonNamespaceUri is in scope
  1164. // if it isn't then add it to document and namespace manager
  1165. string jsonPrefix = manager.LookupPrefix(JsonNamespaceUri);
  1166. if (jsonPrefix == null)
  1167. {
  1168. // ensure that the prefix used is free
  1169. int? i = null;
  1170. while (manager.LookupNamespace("json" + i) != null)
  1171. {
  1172. i = i.GetValueOrDefault() + 1;
  1173. }
  1174. jsonPrefix = "json" + i;
  1175. attributeNameValues.Add("xmlns:" + jsonPrefix, JsonNamespaceUri);
  1176. manager.AddNamespace(jsonPrefix, JsonNamespaceUri);
  1177. }
  1178. attributeNameValues.Add(jsonPrefix + ":" + attributeName, attributeValue);
  1179. break;
  1180. default:
  1181. finishedAttributes = true;
  1182. break;
  1183. }
  1184. }
  1185. else
  1186. {
  1187. finishedAttributes = true;
  1188. }
  1189. break;
  1190. case JsonToken.EndObject:
  1191. finishedElement = true;
  1192. break;
  1193. default:
  1194. throw new JsonSerializationException("Unexpected JsonToken: " + reader.TokenType);
  1195. }
  1196. }
  1197. }
  1198. return attributeNameValues;
  1199. }
  1200. private void CreateInstruction(JsonReader reader, IXmlDocument document, IXmlNode currentNode, string propertyName)
  1201. {
  1202. if (propertyName == DeclarationName)
  1203. {
  1204. string version = null;
  1205. string encoding = null;
  1206. string standalone = null;
  1207. while (reader.Read() && reader.TokenType != JsonToken.EndObject)
  1208. {
  1209. switch (reader.Value.ToString())
  1210. {
  1211. case "@version":
  1212. reader.Read();
  1213. version = reader.Value.ToString();
  1214. break;
  1215. case "@encoding":
  1216. reader.Read();
  1217. encoding = reader.Value.ToString();
  1218. break;
  1219. case "@standalone":
  1220. reader.Read();
  1221. standalone = reader.Value.ToString();
  1222. break;
  1223. default:
  1224. throw new JsonSerializationException("Unexpected property name encountered while deserializing XmlDeclaration: " + reader.Value);
  1225. }
  1226. }
  1227. IXmlNode declaration = document.CreateXmlDeclaration(version, encoding, standalone);
  1228. currentNode.AppendChild(declaration);
  1229. }
  1230. else
  1231. {
  1232. IXmlNode instruction = document.CreateProcessingInstruction(propertyName.Substring(1), reader.Value.ToString());
  1233. currentNode.AppendChild(instruction);
  1234. }
  1235. }
  1236. private IXmlElement CreateElement(string elementName, IXmlDocument document, string elementPrefix, XmlNamespaceManager manager)
  1237. {
  1238. string ns = string.IsNullOrEmpty(elementPrefix) ? manager.DefaultNamespace : manager.LookupNamespace(elementPrefix);
  1239. IXmlElement element = (!string.IsNullOrEmpty(ns)) ? document.CreateElement(elementName, ns) : document.CreateElement(elementName);
  1240. return element;
  1241. }
  1242. private void DeserializeNode(JsonReader reader, IXmlDocument document, XmlNamespaceManager manager, IXmlNode currentNode)
  1243. {
  1244. do
  1245. {
  1246. switch (reader.TokenType)
  1247. {
  1248. case JsonToken.PropertyName:
  1249. if (currentNode.NodeType == XmlNodeType.Document && document.DocumentElement != null)
  1250. throw new JsonSerializationException("JSON root object has multiple properties. The root object must have a single property in order to create a valid XML document. Consider specifing a DeserializeRootElementName.");
  1251. string propertyName = reader.Value.ToString();
  1252. reader.Read();
  1253. if (reader.TokenType == JsonToken.StartArray)
  1254. {
  1255. int count = 0;
  1256. while (reader.Read() && reader.TokenType != JsonToken.EndArray)
  1257. {
  1258. DeserializeValue(reader, document, manager, propertyName, currentNode);
  1259. count++;
  1260. }
  1261. if (count == 1 && WriteArrayAttribute)
  1262. {
  1263. IXmlElement arrayElement = currentNode.ChildNodes.CastValid<IXmlElement>().Single(n => n.LocalName == propertyName);
  1264. AddJsonArrayAttribute(arrayElement, document);
  1265. }
  1266. }
  1267. else
  1268. {
  1269. DeserializeValue(reader, document, manager, propertyName, currentNode);
  1270. }
  1271. break;
  1272. case JsonToken.StartConstructor:
  1273. string constructorName = reader.Value.ToString();
  1274. while (reader.Read() && reader.TokenType != JsonToken.EndConstructor)
  1275. {
  1276. DeserializeValue(reader, document, manager, constructorName, currentNode);
  1277. }
  1278. break;
  1279. case JsonToken.Comment:
  1280. currentNode.AppendChild(document.CreateComment((string)reader.Value));
  1281. break;
  1282. case JsonToken.EndObject:
  1283. case JsonToken.EndArray:
  1284. return;
  1285. default:
  1286. throw new JsonSerializationException("Unexpected JsonToken when deserializing node: " + reader.TokenType);
  1287. }
  1288. } while (reader.TokenType == JsonToken.PropertyName || reader.Read());
  1289. // don't read if current token is a property. token was already read when parsing element attributes
  1290. }
  1291. /// <summary>
  1292. /// Checks if the attributeName is a namespace attribute.
  1293. /// </summary>
  1294. /// <param name="attributeName">Attribute name to test.</param>
  1295. /// <param name="prefix">The attribute name prefix if it has one, otherwise an empty string.</param>
  1296. /// <returns>True if attribute name is for a namespace attribute, otherwise false.</returns>
  1297. private bool IsNamespaceAttribute(string attributeName, out string prefix)
  1298. {
  1299. if (attributeName.StartsWith("xmlns", StringComparison.Ordinal))
  1300. {
  1301. if (attributeName.Length == 5)
  1302. {
  1303. prefix = string.Empty;
  1304. return true;
  1305. }
  1306. else if (attributeName[5] == ':')
  1307. {
  1308. prefix = attributeName.Substring(6, attributeName.Length - 6);
  1309. return true;
  1310. }
  1311. }
  1312. prefix = null;
  1313. return false;
  1314. }
  1315. private IEnumerable<IXmlNode> ValueAttributes(IEnumerable<IXmlNode> c)
  1316. {
  1317. return c.Where(a => a.NamespaceUri != JsonNamespaceUri);
  1318. }
  1319. #endregion
  1320. /// <summary>
  1321. /// Determines whether this instance can convert the specified value type.
  1322. /// </summary>
  1323. /// <param name="valueType">Type of the value.</param>
  1324. /// <returns>
  1325. /// <c>true</c> if this instance can convert the specified value type; otherwise, <c>false</c>.
  1326. /// </returns>
  1327. public override bool CanConvert(Type valueType)
  1328. {
  1329. #if !NET20
  1330. if (typeof(XObject).IsAssignableFrom(valueType))
  1331. return true;
  1332. #endif
  1333. #if !(SILVERLIGHT || NETFX_CORE)
  1334. if (typeof(XmlNode).IsAssignableFrom(valueType))
  1335. return true;
  1336. #endif
  1337. return false;
  1338. }
  1339. }
  1340. }
  1341. #endif