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 メソッドと同じ機能を実装する必要がありますが、逆シリアル化の前に、XML ノードではなく JSON をステップ実行する必要があります。JsonConvert を使用して XML に変換し、既存のメソッドでノードを削除してから JSON に戻すという簡単なオプションを使用できません。これは、XML との間の変換によって JSON が変更されるためです。 . XmlNode クラスで提供されているように、C# で JSON 階層をナビゲートする同等の方法はありますか?

アップデート:

この質問は、一部のコメントによって難読化されています。明確にするために、JSON から削除したいノードは、2 番目の「shipments」の 2 番目の「outlet_id」など、同じ親の同じレベルで繰り返される (名前によると、コンテンツは無関係です) ノードです。上記の例のアイテム。ハードコーディングされた要素名を使用せずに、これを一般的な方法で行う必要があります。上記の RemoveDuplicateChildren メソッドはまさに必要なことを行います。XML 文字列の代わりに JSON 文字列に対してそのメソッドとまったく同じことを行うために使用できるクラスがあるかどうかを尋ねているだけです。

4

0 に答える 0