-Optimized serializing XML elements to JSON

This commit is contained in:
James Newton-King
2017-01-17 11:44:04 +13:00
parent 7e4b3448c7
commit ecd137eefa
@@ -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<string, List<IXmlNode>> nodesGroupedByName = null;
// value of dictionary will be a single IXmlNode when there is one for a name,
// or a List<IXmlNode> when there are multiple
Dictionary<string, object> nodesGroupedByName = null;
string nodeName = null;
@@ -1292,26 +1295,41 @@ namespace Newtonsoft.Json.Converters
}
else
{
nodesGroupedByName = new Dictionary<string, List<IXmlNode>>();
List<IXmlNode> nodes = new List<IXmlNode>(i);
for (int j = 0; j < i; j++)
nodesGroupedByName = new Dictionary<string, object>();
if (i > 1)
{
nodes.Add(node.ChildNodes[j]);
List<IXmlNode> nodes = new List<IXmlNode>(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<IXmlNode> { childNode });
else
{
nodesGroupedByName.Add(nodeName, node.ChildNodes[0]);
}
nodesGroupedByName.Add(currentNodeName, childNode);
}
}
else
{
List<IXmlNode> nodes;
if (!nodesGroupedByName.TryGetValue(currentNodeName, out nodes))
object value;
if (!nodesGroupedByName.TryGetValue(currentNodeName, out value))
{
nodes = new List<IXmlNode>();
nodesGroupedByName.Add(currentNodeName, nodes);
nodesGroupedByName.Add(currentNodeName, childNode);
}
else
{
List<IXmlNode> nodes = value as List<IXmlNode>;
if (nodes == null)
{
nodes = new List<IXmlNode> {(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<string, List<IXmlNode>> nodeNameGroup in nodesGroupedByName)
foreach (KeyValuePair<string, object> nodeNameGroup in nodesGroupedByName)
{
WriteGroupedNodes(writer, manager, writePropertyName, nodeNameGroup.Value, nodeNameGroup.Key);
List<IXmlNode> nodes = nodeNameGroup.Value as List<IXmlNode>;
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)