Files
Newtonsoft.Json/Src/Newtonsoft.Json.Tests/XmlNodeConverterTest.cs
T
2008-03-02 03:18:05 +00:00

418 lines
13 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 NUnit.Framework;
using Newtonsoft.Json;
using System.IO;
using System.Xml;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Utilities;
namespace Newtonsoft.Json.Tests
{
public class XmlNodeConverterTest : TestFixtureBase
{
[Test]
public void DocumentSerializeIndented()
{
string xml = @"<?xml version=""1.0"" standalone=""no""?>
<?xml-stylesheet href=""classic.xsl"" type=""text/xml""?>
<span class=""vevent"">
<a class=""url"" href=""http://www.web2con.com/"">
<span class=""summary"">Web 2.0 Conference<![CDATA[my escaped text]]></span>
<abbr class=""dtstart"" title=""2005-10-05"">October 5</abbr>
<abbr class=""dtend"" title=""2005-10-08"">7</abbr>
<span class=""location"">Argent Hotel, San Francisco, CA</span>
</a>
</span>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
StringWriter sw = new StringWriter();
using (JsonWriter jsonWriter = new JsonTextWriter(sw))
{
jsonWriter.Formatting = Formatting.Indented;
JsonSerializer jsonSerializer = new JsonSerializer();
jsonSerializer.Converters.Add(new XmlNodeConverter());
jsonSerializer.Serialize(jsonWriter, doc);
}
string jsonText = sw.ToString();
string expected = @"{
""?xml"": {
""@version"": ""1.0"",
""@standalone"": ""no""
},
""?xml-stylesheet"": ""href=\""classic.xsl\"" type=\""text/xml\"""",
""span"": {
""@class"": ""vevent"",
""a"": {
""@class"": ""url"",
""@href"": ""http://www.web2con.com/"",
""span"": [
{
""@class"": ""summary"",
""#text"": ""Web 2.0 Conference"",
""#cdata-section"": ""my escaped text""
},
{
""@class"": ""location"",
""#text"": ""Argent Hotel, San Francisco, CA""
}
],
""abbr"": [
{
""@class"": ""dtstart"",
""@title"": ""2005-10-05"",
""#text"": ""October 5""
},
{
""@class"": ""dtend"",
""@title"": ""2005-10-08"",
""#text"": ""7""
}
]
}
}
}";
Assert.AreEqual(expected, jsonText);
Console.WriteLine("DocumentSerializeIndented");
Console.WriteLine(jsonText);
Console.WriteLine();
}
[Test]
public void SerializeNodeTypes()
{
XmlDocument doc = new XmlDocument();
string jsonText;
Console.WriteLine("SerializeNodeTypes");
// XmlAttribute
XmlAttribute attribute = doc.CreateAttribute("msdata:IsDataSet");
attribute.Value = "true";
jsonText = JavaScriptConvert.SerializeXmlNode(attribute);
Console.WriteLine(jsonText);
Assert.AreEqual(@"{""@msdata:IsDataSet"":""true""}", jsonText);
// XmlProcessingInstruction
XmlProcessingInstruction instruction = doc.CreateProcessingInstruction("xml-stylesheet", @"href=""classic.xsl"" type=""text/xml""");
jsonText = JavaScriptConvert.SerializeXmlNode(instruction);
Console.WriteLine(jsonText);
Assert.AreEqual(@"{""?xml-stylesheet"":""href=\""classic.xsl\"" type=\""text/xml\""""}", jsonText);
// XmlProcessingInstruction
XmlCDataSection cDataSection = doc.CreateCDataSection("<Kiwi>true</Kiwi>");
jsonText = JavaScriptConvert.SerializeXmlNode(cDataSection);
Console.WriteLine(jsonText);
Assert.AreEqual(@"{""#cdata-section"":""<Kiwi>true</Kiwi>""}", jsonText);
// XmlElement
XmlElement element = doc.CreateElement("xs:Choice");
element.SetAttributeNode(attribute);
element.AppendChild(instruction);
element.AppendChild(cDataSection);
jsonText = JavaScriptConvert.SerializeXmlNode(element);
Console.WriteLine(jsonText);
Assert.AreEqual(@"{""xs:Choice"":{""@msdata:IsDataSet"":""true"",""?xml-stylesheet"":""href=\""classic.xsl\"" type=\""text/xml\"""",""#cdata-section"":""<Kiwi>true</Kiwi>""}}", jsonText);
}
[Test]
public void DocumentFragmentSerialize()
{
XmlDocument doc = new XmlDocument();
XmlDocumentFragment fragement = doc.CreateDocumentFragment();
fragement.InnerXml = "<Item>widget</Item><Item>widget</Item>";
string jsonText = JavaScriptConvert.SerializeXmlNode(fragement);
string expected = @"{""Item"":[""widget"",""widget""]}";
Assert.AreEqual(expected, jsonText);
Console.WriteLine("DocumentFragmentSerialize");
Console.WriteLine(jsonText);
Console.WriteLine();
}
[Test]
public void NamespaceSerializeDeserialize()
{
string xml = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
<xs:schema xs:id=""SomeID""
xmlns=""""
xmlns:xs=""http://www.w3.org/2001/XMLSchema""
xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
<xs:element name=""MyDataSet"" msdata:IsDataSet=""true"">
<xs:complexType>
<xs:choice maxOccurs=""unbounded"">
<xs:element name=""customers"" >
<xs:complexType >
<xs:sequence>
<xs:element name=""CustomerID"" type=""xs:integer""
minOccurs=""0"" />
<xs:element name=""CompanyName"" type=""xs:string""
minOccurs=""0"" />
<xs:element name=""Phone"" type=""xs:string"" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string jsonText = JavaScriptConvert.SerializeXmlNode(doc);
XmlDocument deserializedDoc = (XmlDocument)JavaScriptConvert.DeserializeXmlNode(jsonText);
Assert.AreEqual(doc.InnerXml, deserializedDoc.InnerXml);
Console.WriteLine("NamespaceSerializeDeserialize");
Console.WriteLine(jsonText);
Console.WriteLine(deserializedDoc.InnerXml);
Console.WriteLine();
}
[Test]
public void DocumentDeserialize()
{
string jsonText = @"{
""?xml"": {
""@version"": ""1.0"",
""@standalone"": ""no""
},
""span"": {
""@class"": ""vevent"",
""a"": {
""@class"": ""url"",
""@href"": ""http://www.web2con.com/"",
""span"": {
""@class"": ""summary"",
""#text"": ""Web 2.0 Conference"",
""#cdata-section"": ""my escaped text""
}
}
}
}";
XmlDocument doc = (XmlDocument)JavaScriptConvert.DeserializeXmlNode(jsonText);
string expected = @"<?xml version=""1.0"" standalone=""no""?>
<span class=""vevent"">
<a class=""url"" href=""http://www.web2con.com/"">
<span class=""summary"">Web 2.0 Conference<![CDATA[my escaped text]]></span>
</a>
</span>";
string formattedXml = GetIndentedInnerXml(doc);
Console.WriteLine("DocumentDeserialize");
Console.WriteLine(formattedXml);
Console.WriteLine();
Assert.AreEqual(expected, formattedXml);
}
private string GetIndentedInnerXml(XmlNode node)
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
StringWriter sw = new StringWriter();
using (XmlWriter writer = XmlWriter.Create(sw, settings))
{
node.WriteTo(writer);
}
return sw.ToString();
}
[Test]
public void SingleTextNode()
{
string xml = @"<?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>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string jsonText = JavaScriptConvert.SerializeXmlNode(doc);
XmlDocument newDoc = (XmlDocument)JavaScriptConvert.DeserializeXmlNode(jsonText);
Assert.AreEqual(doc.InnerXml, newDoc.InnerXml);
}
[Test]
public void EmptyNode()
{
string xml = @"<?xml version=""1.0"" standalone=""no""?>
<root>
<person id=""1"">
<name>Alan</name>
<url />
</person>
<person id=""2"">
<name>Louis</name>
<url>http://www.yahoo.com</url>
</person>
</root>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string jsonText = JavaScriptConvert.SerializeXmlNode(doc);
Console.WriteLine(jsonText);
XmlDocument newDoc = (XmlDocument)JavaScriptConvert.DeserializeXmlNode(jsonText);
Assert.AreEqual(doc.InnerXml, newDoc.InnerXml);
}
[Test]
public void OtherElementDataTypes()
{
string jsonText = @"{""?xml"":{""@version"":""1.0"",""@standalone"":""no""},""root"":{""person"":[{""@id"":""1"",""Float"":2.5,""Integer"":99},{""@id"":""2"",""Boolean"":true,""date"":""\/Date(954374400000)\/""}]}}";
XmlDocument newDoc = (XmlDocument)JavaScriptConvert.DeserializeXmlNode(jsonText);
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>";
Assert.AreEqual(expected, newDoc.InnerXml);
}
[Test]
[ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "XmlNodeConverter can only convert JSON that begins with an object.")]
public void NoRootObject()
{
XmlDocument newDoc = (XmlDocument)JavaScriptConvert.DeserializeXmlNode(@"[1]");
}
[Test]
[ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "JSON root object has multiple properties.")]
public void RootObjectMultipleProperties()
{
XmlDocument newDoc = (XmlDocument)JavaScriptConvert.DeserializeXmlNode(@"{Prop1:1,Prop2:2}");
}
[Test]
public void JavaScriptConstructor()
{
string jsonText = @"{root:{r:new Date(34343, 55)}}";
XmlDocument newDoc = (XmlDocument)JavaScriptConvert.DeserializeXmlNode(jsonText);
string expected = @"<root><r><-Date>34343</-Date><-Date>55</-Date></r></root>";
Assert.AreEqual(expected, newDoc.InnerXml);
string json = JavaScriptConvert.SerializeXmlNode(newDoc);
Assert.AreEqual(@"{""root"":{""r"":new Date(""34343"",""55"")}}", json);
}
[Test]
public void ForceJsonArray()
{
string arrayXml = @"<root xmlns:json=""http://james.newtonking.com/projects/json"">
<person id=""1"">
<name>Alan</name>
<url>http://www.google.com</url>
<role json:Array=""true"">Admin</role>
</person>
</root>";
XmlDocument arrayDoc = new XmlDocument();
arrayDoc.LoadXml(arrayXml);
string arrayJsonText = JavaScriptConvert.SerializeXmlNode(arrayDoc);
Assert.AreEqual(@"{""root"":{""person"":{""@id"":""1"",""name"":""Alan"",""url"":""http://www.google.com"",""role"":[""Admin""]}}}", arrayJsonText);
arrayXml = @"<root xmlns:json=""http://james.newtonking.com/projects/json"">
<person id=""1"">
<name>Alan</name>
<url>http://www.google.com</url>
<role json:Array=""true"">Admin1</role>
<role json:Array=""true"">Admin2</role>
</person>
</root>";
arrayDoc = new XmlDocument();
arrayDoc.LoadXml(arrayXml);
arrayJsonText = JavaScriptConvert.SerializeXmlNode(arrayDoc);
Assert.AreEqual(@"{""root"":{""person"":{""@id"":""1"",""name"":""Alan"",""url"":""http://www.google.com"",""role"":[""Admin1"",""Admin2""]}}}", arrayJsonText);
arrayXml = @"<root xmlns:json=""http://james.newtonking.com/projects/json"">
<person id=""1"">
<name>Alan</name>
<url>http://www.google.com</url>
<role json:Array=""false"">Admin1</role>
</person>
</root>";
arrayDoc = new XmlDocument();
arrayDoc.LoadXml(arrayXml);
arrayJsonText = JavaScriptConvert.SerializeXmlNode(arrayDoc);
Assert.AreEqual(@"{""root"":{""person"":{""@id"":""1"",""name"":""Alan"",""url"":""http://www.google.com"",""role"":""Admin1""}}}", arrayJsonText);
}
}
}