-Fixed converting dollar JSON properties to XML

This commit is contained in:
James Newton-King
2016-04-29 23:19:42 +12:00
parent ad7752fedf
commit b71ca75905
3 changed files with 95 additions and 48 deletions
@@ -130,6 +130,36 @@ namespace Newtonsoft.Json.Tests.Converters
}
#if !NET20
[Test]
public void SerializeDollarProperty()
{
string json1 = @"{""$"":""test""}";
var doc = JsonConvert.DeserializeXNode(json1);
Assert.AreEqual(@"<_x0024_>test</_x0024_>", doc.ToString());
var json2 = JsonConvert.SerializeXNode(doc);
Assert.AreEqual(json1, json2);
}
[Test]
public void SerializeNonKnownDollarProperty()
{
string json1 = @"{""$JELLY"":""test""}";
var doc = JsonConvert.DeserializeXNode(json1);
Console.WriteLine(doc.ToString());
Assert.AreEqual(@"<_x0024_JELLY>test</_x0024_JELLY>", doc.ToString());
var json2 = JsonConvert.SerializeXNode(doc);
Assert.AreEqual(json1, json2);
}
public class MyModel
{
public string MyProperty { get; set; }
@@ -23,10 +23,9 @@
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
#if !(NET20 || NET35 || NET40 || NETFX_CORE || PORTABLE || PORTABLE40 || DNXCORE50)
#if !(NET20 || NET35 || NET40 || NETFX_CORE || PORTABLE40 || DNXCORE50)
using System.Xml;
using System;
using System.Buffers;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
@@ -258,6 +257,7 @@ namespace Newtonsoft.Json.Tests
}
#if !(PORTABLE40)
#if !(PORTABLE)
[Test]
public void ConvertXmlNode()
{
@@ -269,6 +269,7 @@ namespace Newtonsoft.Json.Tests
JsonConvert.SerializeXmlNode(doc);
}
#endif
[Test]
public void ConvertXNode()
@@ -1540,26 +1540,30 @@ namespace Newtonsoft.Json.Converters
string attributePrefix = MiscellaneousUtils.GetPrefix(attributeName);
AddAttribute(reader, document, currentNode, attributeName, manager, attributePrefix);
return;
}
else if (propertyName.StartsWith('$'))
if (propertyName.StartsWith('$'))
{
if (propertyName == JsonTypeReflector.ArrayValuesPropertyName)
switch (propertyName)
{
propertyName = propertyName.Substring(1);
elementPrefix = manager.LookupPrefix(JsonNamespaceUri);
CreateElement(reader, document, currentNode, propertyName, manager, elementPrefix, attributeNameValues);
}
else
{
string attributeName = propertyName.Substring(1);
string attributePrefix = manager.LookupPrefix(JsonNamespaceUri);
AddAttribute(reader, document, currentNode, attributeName, manager, attributePrefix);
case JsonTypeReflector.ArrayValuesPropertyName:
propertyName = propertyName.Substring(1);
elementPrefix = manager.LookupPrefix(JsonNamespaceUri);
CreateElement(reader, document, currentNode, propertyName, manager, elementPrefix, attributeNameValues);
return;
case JsonTypeReflector.IdPropertyName:
case JsonTypeReflector.RefPropertyName:
case JsonTypeReflector.TypePropertyName:
case JsonTypeReflector.ValuePropertyName:
string attributeName = propertyName.Substring(1);
string attributePrefix = manager.LookupPrefix(JsonNamespaceUri);
AddAttribute(reader, document, currentNode, attributeName, manager, attributePrefix);
return;
}
}
else
{
CreateElement(reader, document, currentNode, propertyName, manager, elementPrefix, attributeNameValues);
}
CreateElement(reader, document, currentNode, propertyName, manager, elementPrefix, attributeNameValues);
}
private void CreateElement(JsonReader reader, IXmlDocument document, IXmlNode currentNode, string elementName, XmlNamespaceManager manager, string elementPrefix, Dictionary<string, string> attributeNameValues)
@@ -1776,40 +1780,52 @@ namespace Newtonsoft.Json.Converters
}
break;
case '$':
// check that JsonNamespaceUri is in scope
// if it isn't then add it to document and namespace manager
string jsonPrefix = manager.LookupPrefix(JsonNamespaceUri);
if (jsonPrefix == null)
switch (attributeName)
{
// ensure that the prefix used is free
int? i = null;
while (manager.LookupNamespace("json" + i) != null)
{
i = i.GetValueOrDefault() + 1;
}
jsonPrefix = "json" + i;
case JsonTypeReflector.ArrayValuesPropertyName:
case JsonTypeReflector.IdPropertyName:
case JsonTypeReflector.RefPropertyName:
case JsonTypeReflector.TypePropertyName:
case JsonTypeReflector.ValuePropertyName:
// check that JsonNamespaceUri is in scope
// if it isn't then add it to document and namespace manager
string jsonPrefix = manager.LookupPrefix(JsonNamespaceUri);
if (jsonPrefix == null)
{
// ensure that the prefix used is free
int? i = null;
while (manager.LookupNamespace("json" + i) != null)
{
i = i.GetValueOrDefault() + 1;
}
jsonPrefix = "json" + i;
attributeNameValues.Add("xmlns:" + jsonPrefix, JsonNamespaceUri);
manager.AddNamespace(jsonPrefix, JsonNamespaceUri);
attributeNameValues.Add("xmlns:" + jsonPrefix, JsonNamespaceUri);
manager.AddNamespace(jsonPrefix, JsonNamespaceUri);
}
// special case $values, it will have a non-primitive value
if (attributeName == JsonTypeReflector.ArrayValuesPropertyName)
{
finishedAttributes = true;
break;
}
attributeName = attributeName.Substring(1);
reader.Read();
if (!JsonTokenUtils.IsPrimitiveToken(reader.TokenType))
{
throw JsonSerializationException.Create(reader, "Unexpected JsonToken: " + reader.TokenType);
}
attributeValue = (reader.Value != null) ? reader.Value.ToString() : null;
attributeNameValues.Add(jsonPrefix + ":" + attributeName, attributeValue);
break;
default:
finishedAttributes = true;
break;
}
// special case $values, it will have a non-primitive value
if (attributeName == JsonTypeReflector.ArrayValuesPropertyName)
{
finishedAttributes = true;
break;
}
attributeName = attributeName.Substring(1);
reader.Read();
if (!JsonTokenUtils.IsPrimitiveToken(reader.TokenType))
{
throw JsonSerializationException.Create(reader, "Unexpected JsonToken: " + reader.TokenType);
}
attributeValue = (reader.Value != null) ? reader.Value.ToString() : null;
attributeNameValues.Add(jsonPrefix + ":" + attributeName, attributeValue);
break;
default:
finishedAttributes = true;