【问题标题】:Add data in Json and Merge two json file in C#在 Json 中添加数据并在 C# 中合并两个 json 文件
【发布时间】:2017-09-11 11:48:20
【问题描述】:

我有两个json格式的数据

"@xmlns": "TestValue",
"Complete": {
  "Heights": {
    "Height": {
      "Person": {
        "PersonName": [ {
          "@Name": "Mrx",
          "Attributes": {
            "Attribute": ["Tall", "Small", "Fair", "Intelligente", "Clever", "OnTime" ]
          }
        }
      }
    }
  }
}

像这样还有其他Mry有属性。

这个 json 属于社会上的所有人,还有另一个人 json,它是同一个 json 的子集,但它存储在不同的文件中。

有两个json文件:allPerson.jsonapecialPerson.json

我这里要执行两个操作:

  1. 我在 allPerson.json 中添加 HasPass="N" 值,在 specialPerson.json 中添加 HasPass="Y"

所以 json 对于allPerson.json应该是这样的

"@xmlns": "TestValue",
"Complete": {
  "Heights": {
    "Height": {
      "Person": {
        "PersonName": [ {
          "@Name": "Mrx",
          "Attributes": {
            "Attribute": [ "Tall" HasPass="N", "Small" HasPass="N", "Fair" HasPass="N", "Intelligente" HasPass="N", "Clever" HasPass="N", "OnTime" HasPass="N"
            ]
          }
        }
      }
    }
  }
}

对于specialPerson.json HasPass="Y" 在值级别上。

  1. 在此之后,我必须合并所有两个 json 以创建一个合并 json 文件merge.json,它将从allperson.jsonspecialPerson.json 中获取值

如果两个文件有共同的数据,它将采用 HasPass="Y" 的那些值

MergeJson 看起来像这样

"@xmlns": "TestValue",
"Complete": {
  "Heights": {
    "Height": {
      "Person": {
        "PersonName": [{
          "@Name": "Mrx",
          "Attributes": {
            "Attribute": [ "Tall" HasPass="Y", "Small" HasPass="N", "Fair" HasPass="Y", "Intelligente" HasPass="N", "Clever" HasPass="Y", "OnTime" HasPass="N" ]
          }
        }
      }
    }
  }
}

【问题讨论】:

  • 我已尝试格式化您的问题以更好地理解它,但 Attribute 数组似乎 JSON 格式错误。请确保更新您的问题以反映 Attribute 的外观。如果Tall 同时拥有 HasPass="Y" 和 HasPass="N",如何合并?
  • 首先需要 HasPass="N" 为 allPerson.json 中的所有属性值和 HasPass="Y" 为 specialPerson.json 中的所有属性,然后需要合并两个文件。如果文件中都存在 Mrx 并且具有 Tall 属性,则在合并文件中采用 HasPass="Y",其他属性值为 hasPass="N"。希望这次我清楚了。
  • Tall 属性同时具有HasPass="Y"HasPass="N" 时,请为Tall 属性提供预期json 的有效示例
  • 我想说的是,首先,"Attribute": [ "Tall" HasPass="Y" ] 无效JSON,其次,合并后"Attribute": [ "Tall" HasPass="Y" HasPass="N" ] 应该是什么样子?
  • 它应该像 "Attribute": [ "Tall":{ HasPass="Y"} ] 合并后它也应该像这样只有 "Attribute": [ "Tall":{ HasPass ="Y"} ] 如果 Tall 对两个 Json 来说都是通用的,则基于条件

标签: json c#-4.0 json.net key-value


【解决方案1】:
class PersonName
{
    [JProperty("@Name")]
    public string Name { get; set; }

    public Attributes Attributes { get; set; }
}

class Attributes
{
    public List<Dictionalry<string, AttributeHassPass>> Attribute { get; set; }
}

class AttributeHassPass
{
    public string HassPass { get; set; }
}

反序列化第一个文件你会得到类似的东西:

persons ... probably list initialized like:

{
    new Person()
    {
        PersonName = new PersonName()
        {
            Name = "Mrx",
            Attributes = new Attributes()
            {
                Attribute = new List<Dictionalry<string, AttributeHassPass>>()
                {
                    new Dictionalry<string, AttributeHassPass>()
                    {
                        { "Tall", null }
                    }
                    new Dictionalry<string, AttributeHassPass>()
                    {
                        { "Small", null }
                    }
                    ...
                }
            }
        }
    }
}

personName 在实际示例中将是一个人的财产,依此类推。

当您将遍历人员时,您现在可以更新其属性:

foreach (var dictionary in personName.Attributes.Attribute)
{
    foreach (var kvp in dictionary)
    {
        kvp.Value = new AttributeHassPass()
        {
            HassPass = "N"
        }
    }
}

第二个文件也是如此。

然后,当您需要合并时,最好的方法是首先从第二个文件中的人员创建字典以便于查找:

// Find out how to get it better or from where.
IDictionary<string, Attributes> lookup = persons2.ToDictionary(p => p.Name, p => p.Attributes);

然后你合并。遍历第一个文件中的人员并从 secong 中查找人员以查看是否有要合并的属性:

foreach (var person in persons1)
{
    // Get name of a person from first file.
    var name = person.PersonName.Name;

    // Lookup the name from second file.
    Attributes attributes;
    if (lookup.TryGetValue(name, out attributes))
    {
        // We found value to merge.
        foreach (var dictionary in person.PersonName.Attributes.Attribute)
        {
            foreach (var kvp in dictionary)
            {
                var matchingAttribute = attributes.Attribute.Select(dict => dict.ContainsKey(kvp.Key)).SingleOrDefault();
                if (matchingAttribute != null)
                {
                    // It means we have found an attrubite to merge.
                    kvp.HassPass = matchingAttribute.First().HassPass;
                }
            }
        }
    }
}

毕竟来自第一个文件的人将具有来自第二个文件的合并属性。

我知道这很混乱,但是如果不知道确切的 json 结构,我就无法做更好的例子。您在问题中提供的内容并不完全正确。但我希望你现在知道如何继续前进。

【讨论】:

  • 非常感谢您的详细回答。我有一个模型类,其中我的 Attributes 类是 List for allPerson.json,并且当我将 Attributes 的模型类从 List 更改为 Dictionary 时。之后,我调用 DeserializeObject 方法进行反序列化,并在从 List 转换为字典时出错,并且由于模型类的更改破坏了现有代码。我必须反序列化才能添加 hasPass。
  • 我的例子不会 100% 有效,只是为了给你一个想法。如果没有 json 文件和查看结构,很难提供更好的解决方案。但是我认为您可以提供文件以供参考,也可以尝试考虑如何正确反序列化它。
猜你喜欢
  • 1970-01-01
  • 2019-11-13
  • 2017-12-28
  • 1970-01-01
  • 2013-12-15
  • 2016-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多