有没有解析JSON字符串而不反序列化的方法?

时间:2014-12-16 14:45:30

标签: c# json xml deserialization datacontractjsonserializer

我正在调用一个Web服务,在某些情况下返回带有重复节点的JSON,提供类似于此的输出:

{
    "shipments": [
        {
            "id": "A000001",
            "name": "20141208 140652",
            "type": "OUTLET",
            "date": "2014-12-08 14:06:52",
            "status": "SENT",
            "received_at": null,
            "created_at": "2014-12-08 14:06:52",
            "updated_at": null,
            "outlet_id": "SH000064"
        },
        {
            "id": "A000002",
            "name": "20141204 122650",
            "type": "SUPPLIER",
            "date": "2014-12-04 12:26:50",
            "outlet_id": "SH000064",
            "supplier_id": null,
            "status": "RECEIVED",
            "outlet_id": "SH000064",
            "received_at": "2014-12-04 12:28:43",
            "created_at": "2014-12-04 12:26:50",
            "updated_at": "2014-12-04 12:28:43"
        }
    ]
}

我依赖服务的提供者来解决这个问题,这不是他们的优先事项所以我必须处理它。为了解决这个问题,我使用JsonReaderWriterFactory将JSON转换为XML,然后使用以下例程从生成的XML中删除重复的节点:

protected virtual void RemoveDuplicateChildren(XmlNode node)
{
    if (node.NodeType != XmlNodeType.Element || !node.HasChildNodes)
    {
        return;
    }

    var xNode = XElement.Load(node.CreateNavigator().ReadSubtree());
    var duplicateNames = new List<string>();

    foreach (XmlNode child in node.ChildNodes)
    {
        var isBottom = this.IsBottomElement(child); // Has no XmlNodeType.Element type children

        if (!isBottom)
        {
            this.RemoveDuplicateChildren(child);
        }
        else
        {
            var count = xNode.Elements(child.Name).Count();

            if (count > 1 && !duplicateNames.Contains(child.Name))
            {
                duplicateNames.Add(child.Name);
            }
        }
    }

    if (duplicateNames.Count > 0)
    {
        foreach (var duplicate in duplicateNames)
        {
            var nodeList =  node.SelectNodes(duplicate);

            if (nodeList.Count > 1)
            {
                for (int i=1; i<nodeList.Count; i++)
                {
                    node.RemoveChild(nodeList[i]);
                 }
             }
        }
    }
}

我现在在一个单独的区域中需要使用DataContractJsonSerializer将JSON反序列化为强类型对象,使用以下代码:

DataContractJsonSerializer serialiser = new DataContractJsonSerializer(typeof(ShipmentList));
MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json));

var result = serialiser.ReadObject(stream);

当JSON包含该重复节点时,这会失败,因此我需要在反序列化之前实现与RemoveDuplicateChildren方法相同的功能,但是要逐步执行JSON而不是XML节点。我无法使用快速而肮脏的选项使用JsonConvert转换为XML,使用现有方法删除节点,然后转换回JSON,因为转换为和将导致JSON的更改来自XML。是否有一种等效的方式来导航C#中的JSON层次结构,如XmlNode类所提供的那样?

更新:

这个问题已经被一些评论混淆了。为了澄清,我想从JSON中删除的节点是在同一父级的同一级别上重复(按名称,内容不相关)的任何节点,例如第二个&#34; outlet_id&#34;第二批货#34;上例中的项目。我需要以通用的方式执行此操作,而不使用硬编码元素名称。上面的RemoveDuplicateChildren方法完全可以满足需要,我只是询问是否有一个类可以用来与JSON字符串而不是XML字符串完全相同。

0 个答案:

没有答案