diff --git a/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs b/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs index 8f0f872d..3521054e 100644 --- a/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs +++ b/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs @@ -1271,7 +1271,10 @@ namespace Newtonsoft.Json.Converters { // check whether nodes have the same name // if they don't then group into dictionary together by name - Dictionary> nodesGroupedByName = null; + + // value of dictionary will be a single IXmlNode when there is one for a name, + // or a List when there are multiple + Dictionary nodesGroupedByName = null; string nodeName = null; @@ -1292,26 +1295,41 @@ namespace Newtonsoft.Json.Converters } else { - nodesGroupedByName = new Dictionary>(); - List nodes = new List(i); - for (int j = 0; j < i; j++) + nodesGroupedByName = new Dictionary(); + if (i > 1) { - nodes.Add(node.ChildNodes[j]); + List nodes = new List(i); + for (int j = 0; j < i; j++) + { + nodes.Add(node.ChildNodes[j]); + } + nodesGroupedByName.Add(nodeName, nodes); } - nodesGroupedByName.Add(nodeName, nodes); - nodesGroupedByName.Add(currentNodeName, new List { childNode }); + else + { + nodesGroupedByName.Add(nodeName, node.ChildNodes[0]); + } + nodesGroupedByName.Add(currentNodeName, childNode); } } else { - List nodes; - if (!nodesGroupedByName.TryGetValue(currentNodeName, out nodes)) + object value; + if (!nodesGroupedByName.TryGetValue(currentNodeName, out value)) { - nodes = new List(); - nodesGroupedByName.Add(currentNodeName, nodes); + nodesGroupedByName.Add(currentNodeName, childNode); } + else + { + List nodes = value as List; + if (nodes == null) + { + nodes = new List {(IXmlNode)value}; + nodesGroupedByName[currentNodeName] = nodes; + } - nodes.Add(childNode); + nodes.Add(childNode); + } } } @@ -1323,9 +1341,17 @@ namespace Newtonsoft.Json.Converters { // loop through grouped nodes. write single name instances as normal, // write multiple names together in an array - foreach (KeyValuePair> nodeNameGroup in nodesGroupedByName) + foreach (KeyValuePair nodeNameGroup in nodesGroupedByName) { - WriteGroupedNodes(writer, manager, writePropertyName, nodeNameGroup.Value, nodeNameGroup.Key); + List nodes = nodeNameGroup.Value as List; + if (nodes != null) + { + WriteGroupedNodes(writer, manager, writePropertyName, nodes, nodeNameGroup.Key); + } + else + { + WriteGroupedNodes(writer, manager, writePropertyName, (IXmlNode)nodeNameGroup.Value, nodeNameGroup.Key); + } } } break; @@ -1368,6 +1394,29 @@ namespace Newtonsoft.Json.Converters } } + private void WriteGroupedNodes(JsonWriter writer, XmlNamespaceManager manager, bool writePropertyName, IXmlNode node, string elementNames) + { + bool writeArray = IsArray(node); + + if (!writeArray) + { + SerializeNode(writer, node, manager, writePropertyName); + } + else + { + if (writePropertyName) + { + writer.WritePropertyName(elementNames); + } + + writer.WriteStartArray(); + + SerializeNode(writer, node, manager, false); + + writer.WriteEndArray(); + } + } + private void SerializeNode(JsonWriter writer, IXmlNode node, XmlNamespaceManager manager, bool writePropertyName) { switch (node.NodeType)