private void DeserializeNode(Newtonsoft.Json.JsonReader reader, XmlDocument document, XmlNamespaceManager manager, XmlNode currentNode)
{
if (currentNode.NodeType == XmlNodeType.Document)
{
XmlElement root = document.CreateElement("records");
document.AppendChild(root);
currentNode = root;
}
XmlNode savedNode = currentNode;
do
{
if (savedNode.Name == "records" && savedNode.ParentNode.NodeType == XmlNodeType.Document)
{
currentNode = savedNode;
}
switch (reader.TokenType)
{
case JsonToken.PropertyName:
if (currentNode.NodeType == XmlNodeType.Document && document.DocumentElement != null)
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.");
string propertyName = reader.Value.ToString();
reader.Read();
if (reader.TokenType == JsonToken.StartArray)
{
while (reader.Read() && reader.TokenType != JsonToken.EndArray)
{
if (reader.TokenType == JsonToken.StartObject)
{
if (currentNode.Name == "records" && currentNode.ParentNode.NodeType == XmlNodeType.Document &&
(propertyName == "Updated" || propertyName == "Created" || propertyName == "Deleted"))
{
XmlNode tempNode = currentNode.SelectSingleNode(propertyName);
if (tempNode != null)
{
currentNode = tempNode;
propertyName = "record";
}
}
}
DeserializeValue(reader, document, manager, propertyName, currentNode);
}
}
else
{
bool addRecord = currentNode.ParentNode != null && currentNode.ParentNode.ParentNode != null &&
currentNode.ParentNode.Name == "records" && currentNode.ParentNode.ParentNode.NodeType == XmlNodeType.Document;
if ((currentNode.Name == "Updated" || currentNode.Name == "Created" || currentNode.Name == "Deleted") && addRecord)
{
XmlElement record = document.CreateElement("record");
currentNode.AppendChild(record);
currentNode = record;
}
DeserializeValue(reader, document, manager, propertyName, currentNode);
}
break;
case JsonToken.StartConstructor:
string constructorName = reader.Value.ToString();
while (reader.Read() && reader.TokenType != JsonToken.EndConstructor)
{
DeserializeValue(reader, document, manager, "-" + constructorName, currentNode);
}
break;
case JsonToken.EndObject:
case JsonToken.EndArray:
return;
default:
throw new JsonSerializationException("Unexpected JsonToken when deserializing node: " + reader.TokenType);
}
} while (reader.TokenType == JsonToken.PropertyName || reader.Read());
// don't read if current token is a property. token was already read when parsing element attributes
}