如果不存在,如何通过路径添加JObject属性?

时间:2018-07-12 16:51:47

标签: c# json.net

给出以下代码:

var context = JObject.FromObject(new
                {
                    data = new
                    {
                        mom = "",
                        dad = "",
                        sibling = "",
                        cousin = ""
                    }
                });

var path = "$.data.calculated";

var token = context.SelectToken(path);

token将为空。因此,当然,尝试这样做会产生异常:

token.Replace("500");

我当然也看过其他有关如何向JObject添加属性的示例,但它们似乎都需要您事先了解对象结构。我需要做的是这样的:

if (token == null)
{
    context.Add(path);
    token = context.SelectToken(r.ContextTarget);
}

然后我可以在新令牌上使用replace方法设置其值。但是context.Add(path)抛出异常:

"Can not add Newtonsoft.Json.Linq.JValue to Newtonsoft.Json.Linq.JObject."

如何在不知道现有对象结构的情况下使用像这样的完整路径动态添加属性?

1 个答案:

答案 0 :(得分:0)

虽然这不是万能的(例如,不能正确地处理数组),但它确实可以处理上述简单情况,并且应在层次结构中提供多个级别。

typedef void (*Menu_Processing_Function_Pointer)(void);

struct Menu_Option
{
  char choice;
  char const * p_selection_text;
  Menu_Procesing_Function_Pointer p_procesing_function;
};

void Process_Selection_One();
void Process_Selection_Two();

static const Menu_Option main_menu[] =
{
  {'1', "Option 1", Process_Selection_One},
  {'2', "Option 2", Process_Selection_Two},
};
static const size_t quantity_selections =
    sizeof(main_menu) / sizeof(main_menu[0]);

int main()
{
  static const char menu_title = 
    "\n"
    "------------------------------\n"
    "         Main Menu\n"
    "------------------------------\n"
    ;
  cout.write(menu_title, sizeof(menu_title) - 1);
  for (size_t i = 0; i < quantity_selections; ++i)
  {
    std::cout << main_menu[i].p_selection_text << "\n";
  }
  cout << "Enter selection, 0 to quit: ";
  char choice;
  cin >> choice;
  for (size_t i = 0; i < quantity_selections; ++i)
  {
     if (choice == main_menu[i].choice)
     {
       Menu_Processing_Function_Point p_function = main_menu[i].p_processing_function;
       (p_function)();
       break;
     }
  }
  return EXIT_SUCCESS;
}

以及自己动手部分的肉

if (token == null)
{
    var obj = CreateObjectForPath(path, newValue);                        
    context.Merge(obj);                        
}