469 lines
14 KiB
C#
469 lines
14 KiB
C#
#region License
|
|
// Copyright (c) 2007 James Newton-King
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person
|
|
// obtaining a copy of this software and associated documentation
|
|
// files (the "Software"), to deal in the Software without
|
|
// restriction, including without limitation the rights to use,
|
|
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
// copies of the Software, and to permit persons to whom the
|
|
// Software is furnished to do so, subject to the following
|
|
// conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be
|
|
// included in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
// OTHER DEALINGS IN THE SOFTWARE.
|
|
#endregion
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Text;
|
|
using System.Xml;
|
|
using Newtonsoft.Json.Linq;
|
|
#if DNXCORE50
|
|
using Xunit;
|
|
using Test = Xunit.FactAttribute;
|
|
using Assert = Newtonsoft.Json.Tests.XUnitAssert;
|
|
#else
|
|
using NUnit.Framework;
|
|
|
|
#endif
|
|
|
|
#if !(DNXCORE50 || NET20) || NETSTANDARD2_0 || NET6_0_OR_GREATER
|
|
|
|
namespace Newtonsoft.Json.Tests.Documentation.Samples.Json
|
|
{
|
|
|
|
#region Types
|
|
public class XmlJsonWriter : JsonWriter
|
|
{
|
|
private readonly XmlWriter _writer;
|
|
private string _propertyName;
|
|
|
|
public XmlJsonWriter(XmlWriter writer)
|
|
{
|
|
_writer = writer;
|
|
}
|
|
|
|
public override void WriteComment(string text)
|
|
{
|
|
base.WriteComment(text);
|
|
_writer.WriteComment(text);
|
|
}
|
|
|
|
public override void WritePropertyName(string name)
|
|
{
|
|
base.WritePropertyName(name);
|
|
_propertyName = name;
|
|
}
|
|
|
|
public override void WriteNull()
|
|
{
|
|
base.WriteNull();
|
|
|
|
WriteValueElement(JTokenType.Null);
|
|
_writer.WriteEndElement();
|
|
}
|
|
|
|
public override void WriteValue(DateTime value)
|
|
{
|
|
base.WriteValue(value);
|
|
|
|
WriteValueElement(JTokenType.Date);
|
|
_writer.WriteValue(value);
|
|
_writer.WriteEndElement();
|
|
}
|
|
|
|
public override void WriteValue(DateTimeOffset value)
|
|
{
|
|
base.WriteValue(value);
|
|
|
|
WriteValueElement(JTokenType.Date);
|
|
_writer.WriteValue(value);
|
|
_writer.WriteEndElement();
|
|
}
|
|
|
|
public override void WriteValue(Guid value)
|
|
{
|
|
base.WriteValue(value);
|
|
|
|
WriteValueElement(JTokenType.Guid);
|
|
_writer.WriteValue(value.ToString());
|
|
_writer.WriteEndElement();
|
|
}
|
|
|
|
public override void WriteValue(TimeSpan value)
|
|
{
|
|
base.WriteValue(value);
|
|
|
|
WriteValueElement(JTokenType.TimeSpan);
|
|
_writer.WriteValue(value);
|
|
_writer.WriteEndElement();
|
|
}
|
|
|
|
public override void WriteValue(Uri value)
|
|
{
|
|
base.WriteValue(value);
|
|
|
|
WriteValueElement(JTokenType.Uri);
|
|
_writer.WriteValue(value);
|
|
_writer.WriteEndElement();
|
|
}
|
|
|
|
public override void WriteValue(string value)
|
|
{
|
|
base.WriteValue(value);
|
|
|
|
WriteValueElement(JTokenType.String);
|
|
_writer.WriteValue(value);
|
|
_writer.WriteEndElement();
|
|
}
|
|
|
|
public override void WriteValue(int value)
|
|
{
|
|
base.WriteValue(value);
|
|
|
|
WriteValueElement(JTokenType.Integer);
|
|
_writer.WriteValue(value);
|
|
_writer.WriteEndElement();
|
|
}
|
|
|
|
public override void WriteValue(long value)
|
|
{
|
|
base.WriteValue(value);
|
|
|
|
WriteValueElement(JTokenType.Integer);
|
|
_writer.WriteValue(value);
|
|
_writer.WriteEndElement();
|
|
}
|
|
|
|
public override void WriteValue(short value)
|
|
{
|
|
base.WriteValue(value);
|
|
|
|
WriteValueElement(JTokenType.Integer);
|
|
_writer.WriteValue(value);
|
|
_writer.WriteEndElement();
|
|
}
|
|
|
|
public override void WriteValue(byte value)
|
|
{
|
|
base.WriteValue(value);
|
|
|
|
WriteValueElement(JTokenType.Integer);
|
|
_writer.WriteValue(value);
|
|
_writer.WriteEndElement();
|
|
}
|
|
|
|
public override void WriteValue(bool value)
|
|
{
|
|
base.WriteValue(value);
|
|
|
|
WriteValueElement(JTokenType.Boolean);
|
|
_writer.WriteValue(value);
|
|
_writer.WriteEndElement();
|
|
}
|
|
|
|
public override void WriteValue(char value)
|
|
{
|
|
base.WriteValue(value);
|
|
|
|
WriteValueElement(JTokenType.String);
|
|
_writer.WriteValue(value.ToString(CultureInfo.InvariantCulture));
|
|
_writer.WriteEndElement();
|
|
}
|
|
|
|
public override void WriteValue(decimal value)
|
|
{
|
|
base.WriteValue(value);
|
|
|
|
WriteValueElement(JTokenType.Float);
|
|
_writer.WriteValue(value);
|
|
_writer.WriteEndElement();
|
|
}
|
|
|
|
public override void WriteValue(double value)
|
|
{
|
|
base.WriteValue(value);
|
|
|
|
WriteValueElement(JTokenType.Float);
|
|
_writer.WriteValue(value);
|
|
_writer.WriteEndElement();
|
|
}
|
|
|
|
public override void WriteValue(float value)
|
|
{
|
|
base.WriteValue(value);
|
|
|
|
WriteValueElement(JTokenType.Float);
|
|
_writer.WriteValue(value);
|
|
_writer.WriteEndElement();
|
|
}
|
|
|
|
private void WriteValueElement(JTokenType type)
|
|
{
|
|
if (_propertyName != null)
|
|
{
|
|
WriteValueElement(_propertyName, type);
|
|
_propertyName = null;
|
|
}
|
|
else
|
|
{
|
|
WriteValueElement("Item", type);
|
|
}
|
|
}
|
|
|
|
private void WriteValueElement(string elementName, JTokenType type)
|
|
{
|
|
_writer.WriteStartElement(elementName);
|
|
_writer.WriteAttributeString("type", type.ToString());
|
|
}
|
|
|
|
public override void WriteStartArray()
|
|
{
|
|
bool isStart = (WriteState == WriteState.Start);
|
|
|
|
base.WriteStartArray();
|
|
|
|
if (isStart)
|
|
{
|
|
WriteValueElement("Root", JTokenType.Array);
|
|
}
|
|
else
|
|
{
|
|
WriteValueElement(JTokenType.Array);
|
|
}
|
|
}
|
|
|
|
public override void WriteStartObject()
|
|
{
|
|
bool isStart = (WriteState == WriteState.Start);
|
|
|
|
base.WriteStartObject();
|
|
|
|
if (isStart)
|
|
{
|
|
WriteValueElement("Root", JTokenType.Object);
|
|
}
|
|
else
|
|
{
|
|
WriteValueElement(JTokenType.Object);
|
|
}
|
|
}
|
|
|
|
public override void WriteStartConstructor(string name)
|
|
{
|
|
bool isStart = (WriteState == WriteState.Start);
|
|
|
|
base.WriteStartConstructor(name);
|
|
|
|
if (isStart)
|
|
{
|
|
WriteValueElement("Root", JTokenType.Constructor);
|
|
}
|
|
else
|
|
{
|
|
WriteValueElement(JTokenType.Constructor);
|
|
}
|
|
|
|
_writer.WriteAttributeString("name", name);
|
|
}
|
|
|
|
public override void WriteEndArray()
|
|
{
|
|
base.WriteEndArray();
|
|
_writer.WriteEndElement();
|
|
}
|
|
|
|
public override void WriteEndObject()
|
|
{
|
|
base.WriteEndObject();
|
|
_writer.WriteEndElement();
|
|
}
|
|
|
|
public override void WriteEndConstructor()
|
|
{
|
|
base.WriteEndConstructor();
|
|
_writer.WriteEndElement();
|
|
}
|
|
|
|
public override void Flush()
|
|
{
|
|
_writer.Flush();
|
|
}
|
|
|
|
protected override void WriteIndent()
|
|
{
|
|
_writer.WriteWhitespace(Environment.NewLine);
|
|
|
|
// levels of indentation multiplied by the indent count
|
|
int currentIndentCount = Top * 2;
|
|
|
|
while (currentIndentCount > 0)
|
|
{
|
|
// write up to a max of 10 characters at once to avoid creating too many new strings
|
|
int writeCount = Math.Min(currentIndentCount, 10);
|
|
|
|
_writer.WriteWhitespace(new string(' ', writeCount));
|
|
|
|
currentIndentCount -= writeCount;
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
[TestFixture]
|
|
public class CustomJsonWriter : TestFixtureBase
|
|
{
|
|
[Test]
|
|
public void Example()
|
|
{
|
|
#region Usage
|
|
var user = new
|
|
{
|
|
Name = "James",
|
|
Age = 30,
|
|
Enabled = true,
|
|
Roles = new[]
|
|
{
|
|
"Publisher",
|
|
"Administrator"
|
|
}
|
|
};
|
|
|
|
StringWriter sw = new StringWriter();
|
|
|
|
using (XmlWriter xmlWriter = XmlWriter.Create(sw, new XmlWriterSettings { OmitXmlDeclaration = true }))
|
|
using (XmlJsonWriter writer = new XmlJsonWriter(xmlWriter))
|
|
{
|
|
writer.Formatting = Formatting.Indented;
|
|
|
|
JsonSerializer serializer = new JsonSerializer();
|
|
serializer.Serialize(writer, user);
|
|
}
|
|
|
|
Console.WriteLine(sw.ToString());
|
|
//<Root type="Object">
|
|
// <Name type="String">James</Name>
|
|
// <Age type="Integer">30</Age>
|
|
// <Enabled type="Boolean">true</Enabled>
|
|
// <Roles type="Array">
|
|
// <Item type="String">Publisher</Item>
|
|
// <Item type="String">Administrator</Item>
|
|
// </Roles>
|
|
//</Root>
|
|
#endregion
|
|
|
|
sw = new StringWriter();
|
|
|
|
using (XmlWriter xmlWriter = XmlWriter.Create(sw, new XmlWriterSettings { OmitXmlDeclaration = true }))
|
|
using (XmlJsonWriter writer = new XmlJsonWriter(xmlWriter))
|
|
{
|
|
writer.Formatting = Formatting.Indented;
|
|
|
|
writer.WriteStartObject();
|
|
|
|
writer.WritePropertyName("Null");
|
|
writer.WriteNull();
|
|
|
|
writer.WritePropertyName("String");
|
|
writer.WriteValue("This is a string!");
|
|
|
|
writer.WritePropertyName("Char");
|
|
writer.WriteValue('!');
|
|
|
|
writer.WritePropertyName("Integer");
|
|
writer.WriteValue(123);
|
|
|
|
writer.WritePropertyName("DateTime");
|
|
writer.WriteValue(new DateTime(2001, 2, 22, 20, 59, 59, DateTimeKind.Utc));
|
|
|
|
writer.WritePropertyName("DateTimeOffset");
|
|
writer.WriteValue(new DateTimeOffset(2001, 2, 22, 20, 59, 59, TimeSpan.FromHours(12)));
|
|
|
|
writer.WritePropertyName("Float");
|
|
writer.WriteValue(1.1f);
|
|
|
|
writer.WritePropertyName("Double");
|
|
writer.WriteValue(3.14d);
|
|
|
|
writer.WritePropertyName("Decimal");
|
|
writer.WriteValue(19.95m);
|
|
|
|
writer.WritePropertyName("Guid");
|
|
writer.WriteValue(Guid.NewGuid());
|
|
|
|
writer.WritePropertyName("Uri");
|
|
writer.WriteValue(new Uri("http://james.newtonking.com"));
|
|
|
|
writer.WritePropertyName("Array");
|
|
writer.WriteStartArray();
|
|
writer.WriteValue(1);
|
|
writer.WriteValue(2);
|
|
writer.WriteValue(3);
|
|
writer.WriteEndArray();
|
|
|
|
writer.WritePropertyName("Object");
|
|
writer.WriteStartObject();
|
|
writer.WritePropertyName("String");
|
|
writer.WriteValue("This is a string!");
|
|
writer.WritePropertyName("Null");
|
|
writer.WriteNull();
|
|
writer.WriteEndObject();
|
|
|
|
writer.WritePropertyName("Constructor");
|
|
writer.WriteStartConstructor("Date");
|
|
writer.WriteValue(2000);
|
|
writer.WriteValue(12);
|
|
writer.WriteValue(30);
|
|
writer.WriteEndConstructor();
|
|
|
|
writer.WriteEndObject();
|
|
|
|
writer.Flush();
|
|
}
|
|
|
|
Console.WriteLine(sw.ToString());
|
|
|
|
//<Root type="Object">
|
|
// <Null type="Null" />
|
|
// <String type="String">This is a string!</String>
|
|
// <Char type="String">!</Char>
|
|
// <Integer type="Integer">123</Integer>
|
|
// <DateTime type="Date">2001-02-22T20:59:59Z</DateTime>
|
|
// <DateTimeOffset type="Date">2001-02-22T20:59:59+12:00</DateTimeOffset>
|
|
// <Float type="Float">1.1</Float>
|
|
// <Double type="Float">3.14</Double>
|
|
// <Decimal type="Float">19.95</Decimal>
|
|
// <Guid type="Guid">d66eab59-3715-4b35-9e06-fa61c1216eaa</Guid>
|
|
// <Uri type="Uri">http://james.newtonking.com</Uri>
|
|
// <Array type="Array">
|
|
// <Item type="Integer">1</Item>
|
|
// <Item type="Integer">2</Item>
|
|
// <Item type="Integer">3</Item>
|
|
// </Array>
|
|
// <Object type="Object">
|
|
// <String type="String">This is a string!</String>
|
|
// <Null type="Null" />
|
|
// </Object>
|
|
// <Constructor type="Constructor" name="Date">
|
|
// <Item type="Integer">2000</Item>
|
|
// <Item type="Integer">12</Item>
|
|
// <Item type="Integer">30</Item>
|
|
// </Constructor>
|
|
//</Root>
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif |