0

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

{
    "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,因为与 XML 的转换会导致 JSON 发生变化. 是否有与 XmlNode 类提供的在 C# 中导航 JSON 层次结构的等效方法?

更新:

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

4

0 回答 0