Работа с JSON

BAZAg

Client
Регистрация
08.11.2015
Сообщения
2 400
Реакции
2 807
Баллы
113
Есть у меня такой JSON например в строковой переменной json:
JSON:
Развернуть Свернуть Копировать
{
"status":200,
 "0":{"name":"83.221.205.201:4145","work":1,"type":"SOCKS4","speed":145,"upd":"2020-03-15 15:02:41","country":"RU"},
 "1":{"name":"176.123.164.240:40795","work":1,"type":"SOCKS4","speed":417,"upd":"2020-03-15 15:02:41","country":"RU"},
 "limit":18,
 "balans":0
}
Чтобы посмотреть его в переменных ZennoPoster выполняю код:
Код:
Развернуть Свернуть Копировать
project.Json.FromString(json);
Результат вижу примерно такой:
51997


Дальше я хочу перебрать все узлы - и это мне удается без проблем:
Код:
Развернуть Свернуть Копировать
List<string> members = project.Json.GetMembersList();
foreach (string member in members) project.SendInfoToLog(member);
51998


Собственно дальше, я хочу как-то пройтись в цикле по вложенным узлам:
Код:
Развернуть Свернуть Копировать
List<string> members = project.Json.GetMembersList();
foreach (string member in members) {
    project.SendInfoToLog(member);
    var childs_1 = project.Json.GetMember(member.ToString()).GetMembersList();
    var childs_2 = project.Json.GetMember(member).GetMembersList();
}
Но... Это не дает никакого удовлетворительного результата (ошибка...).
Собственно вопрос - что делать в таком случае, когда имя узла число либо начинается с какого-то такого символа, который Зеннопостер потом не может распознать?
Конструкция project.Json.0.name - не срабатывает (да и не удобно так - я же не знаю какие там будут значения...).
Как решать такие задачи, естественно не выбирая значения с такого JSON регулярками?
 
Делай так у меня зенка foreach не обрабатывала
C#:
Развернуть Свернуть Копировать
if(project.Json.Count>0){
    for(intx=0; x<project.Json.Count; x++){
        string proxy = project.Json[x].name;
        string type = project.Json[x].type;
    }
}

ну разумеется вынеси или в список или куда добавлять , код привет как пример
 
  • Оценить
Реакции: Soly и BAZAg
Пока буду использовать вот такой вариант - удалю не нужные узлы, а нужные - соберу в json обратно.
Но, всё таки мне кажется, что есть какой-то более правильный вариант работы и хотелось бы узнать как именно правильно работать (костыль сделать временно думаю мне получилось сделать).
C#:
Развернуть Свернуть Копировать
Dictionary<string,object> dict = Global.ZennoLab.Json.JsonConvert.DeserializeObject<Dictionary<string,object>>(project.Json.ToString());
List<object> result = new List<object>(); // Здесь будут статичные данные - их удалять буду
List<object> temp = new List<object>(); // Здесь временно будут нужные данные
foreach(var d in dict) {
    project.SendInfoToLog(d.Key + " " + d.Value.ToString());
    //Избавляюсь от не нужных мне статичных элементов
    switch(d.Key) {
        case "status":  //result.Add( new { status = d.Value.ToString()});
            break;
        case "limit":     //result.Add( new{ limit = d.Value.ToString()});
            break;
        case "balans":     //result.Add( new { balans = d.Value.ToString()});
            break;
        default: temp.Add( new { proxy = d.Value});
            break;
    }  
}
project.Json.FromString(Global.ZennoLab.Json.JsonConvert.SerializeObject(new{data=temp}));
52001


И уже в цикле, смогу обращаться как:
Код:
Развернуть Свернуть Копировать
project.Json.data[i].proxy.name
 
Последнее редактирование:
  • Оценить
Реакции: xdriver и DevOps
Метод через рекурсию. Слишком большой json, думаю, не стоит использовать.
Просто выводит всех потомков.
Для использования нужно править под себя.

В общий код:
Развернуть Свернуть Копировать
public static void jsnMembers ( IZennoPosterProjectModel  project, dynamic json ) {
   
    List<string> members = json.GetMembersList();
      foreach (string member in members) {
        try {
       project.SendInfoToLog( member );
          jsnMembers( project, json.GetMember( member  ));
        }
    catch (Exception e ) {
     //"------next element--------" ;
       }
    }
   }

Вызываем:
C#:
Развернуть Свернуть Копировать
CC.jsnMembers(project, project.Json);
 
  • Оценить
Реакции: BAZAg
Вот на этом месте будет затык, если потомок называется 1 или 0 или _привет.

P.S. Ошибся - затык не получился - работает перебор производит.
Но, допустим мне нужно вернуть узел project.Json.0.name - как это реализовать с помощью этого метода?

52003
 
Последнее редактирование:
Не будет, я протестировал. Там try catch стоит
 
  • Оценить
Реакции: BAZAg
Просто выводит всех потомков.
C#:
Развернуть Свернуть Копировать
// Имена всех потомков
Dictionary<string, string> all = project.Json.GetAllMembersList();
foreach(string s in all.Keys) project.SendInfoToLog(s);
Проблема же заключается в том, как потом получить значение этого потомка...
Допустим, есть потомок, какой-то с названием 0, 1, 2 (изначально мы эти названия не знаем)
Потом, нам нужно, взять у каждого потомка значение name и type.
Получается, что только данным циклом это можно сделать, где-то временно хранить этого потомка, потом проверять, на каждой итерации не изменился ли он... А если вдруг строки перемешаны в этом словаре - тогда окажется что нужное значение мы не получим (посчитаем что его нет), или для получения каждого нужного значения нужно проверять каждый раз целый этот словарь...
Неужели действительно ничего проще нет?
 
  • Оценить
Реакции: Dorian_Gray и volody00
Возможно так:

C#:
Развернуть Свернуть Копировать
Dictionary<dynamic,dynamic> smth = Global.ZennoLab.Json.JsonConvert.DeserializeObject<Dictionary<dynamic,dynamic>> (project.Variables["json"].Value);
 
  • Оценить
Реакции: volody00 и BAZAg
Возможно так:

C#:
Развернуть Свернуть Копировать
Dictionary<dynamic,dynamic> smth = Global.ZennoLab.Json.JsonConvert.DeserializeObject<Dictionary<dynamic,dynamic>> (project.Variables["json"].Value);
В результате, получился примерно такой код - можно считать, что он будет корректно работать?
C#:
Развернуть Свернуть Копировать
List<string> list = new List<string>();
Dictionary<dynamic,dynamic> smth = Global.ZennoLab.Json.JsonConvert.DeserializeObject<Dictionary<dynamic,dynamic>> (project.Json.ToString());
foreach(var d in smth) {
  project.SendInfoToLog(string.Format(@"{0} {1}",d.Key, d.Value.ToString()));
  try {
     Dictionary<dynamic,dynamic> temp = Global.ZennoLab.Json.JsonConvert.DeserializeObject<Dictionary<dynamic,dynamic>> (d.Value.ToString());
     foreach(var z in temp) project.SendInfoToLog(string.Format(@"{0} {1}",z.Key, z.Value.ToString()));
     list.Add(string.Format(@"{0}://{1}", temp["type"], temp["name"]));
  }
  catch {
     continue;
  }
}
foreach(string proxy in list) project.SendInfoToLog(proxy.ToLower());
 
Последнее редактирование:
C#:
Dictionary<dynamic,dynamic> smth = Global.Zen
Эта строчка, вроде бы сразу всё преобразует. Т.е. foreach не нужен.
Тестировал так:
C#:
Развернуть Свернуть Копировать
return smth["0"].name;
 
  • Оценить
Реакции: BAZAg
Эта строчка, вроде бы сразу всё преобразует. Т.е. foreach не нужен.
Тестировал так:
C#:
Развернуть Свернуть Копировать
return smth["0"].name;
Как взять оттуда все элементы со словаря и добавить их в лист list.Add(string.Format(@"{0}://{1}", temp["type"], temp["name"])) без циклов (чтобы каждому name соответствовал type нужного узла?
 
Не уверен что мое решение с Newton.Json JToken лучше варианта со словарями (вот пример шаблона с подключенными библиотеками, если влом собирать, тут пример с которого адаптировал код) , но все же с задачей справляется:
C#:
Развернуть Свернуть Копировать
List<string> list = new List<string>();
JToken JToken1 = JValue.Parse(project.Variables["JsonVar"].Value);
string proxy_String;
// С каждым циклом углубляемся в JSON-вложенности:
for (int i1=0; i1<JToken1.Count(); i1++) {
    JToken JToken2 = JToken1.ElementAt(i1);
    project.SendInfoToLog("JToken2> " + JToken2.ToString());
    for (int i2=0; i2<JToken2.Count(); i2++) {
        JToken JToken3 = JToken2.ElementAt(i2);
        project.SendInfoToLog("JToken3> " + JToken3.ToString());
        for (int i3=0; i3<JToken3.Count(); i3++) {          
            JToken JToken4 = JToken3.ElementAt(i3);
            project.SendInfoToLog("JToken4> " + JToken4.ToString());
            if (JToken4.ToString().StartsWith("\"name\":"))    {
                proxy_String = JToken3["type"] + "://" + JToken3["name"];
                list.Add(proxy_String);
                continue;
            }
        }
    }
}
foreach(string proxy in list) project.SendInfoToLog(proxy.ToLower());
Костыль тут в поиске имени ключа, хз как его вытянуть, тупо парсил через StartsWith.
 
  • Оценить
Реакции: BAZAg
Почитал всё, что тут написано и остановился для себя на таком варианте. Оставляю на всякий случай, вдруг кто-то (как и я) найдет эту тему из поиска и ему будет сложновато понять вышеописанный код (как и мне =)):

C#:
Развернуть Свернуть Копировать
project.Json.FromString(project.Variables["JSON"].Value); //в переменной JSON у нас json, который надо раскидать по переменным
Dictionary<string, string> all = project.Json.GetAllMembersList(); //сложим всё в словарь
foreach(KeyValuePair<string,string> s in all)
    project.SendInfoToLog(s.Key + "=" + s.Value); //достаем ключ и значение
//all[«название переменной»] - чтобы вытащить значение определенной переменной
 
Последнее редактирование:
Почитал всё, что тут написано и остановился для себя на таком варианте. Оставляю на всякий случай, вдруг кто-то (как и я) найдет эту тему из поиска и ему будет сложновато понять вышеописанный код (как и мне =)):

C#:
Развернуть Свернуть Копировать
project.Json.FromString(project.Variables["JSON"].Value); //в переменной JSON у нас json, который надо раскидать по переменным
Dictionary<string, string> all = project.Json.GetAllMembersList(); //сложим всё в словарь
foreach(KeyValuePair<string,string> s in all)
    project.SendInfoToLog(s.Key + "=" + s.Value); //достаем ключ и значение
//all[«название переменной»] - чтобы вытащить значение определенной переменной

Очень помогло. Теперь бы это всё обратно собрать)
 
Есть такой JSON:
Код:
Развернуть Свернуть Копировать
{"blog.titles.blog": "Блог",
"blog.titles.beginners-section": "Раздел для начинающих",
"blog.descriptions.blog": "Это корпоративный блог."}
который сформирован парсингом многоуровневого JSON такого типа:
Код:
Развернуть Свернуть Копировать
"blog": {
    "titles": {
      "blog": "Блог",
стандартными средствами Зенки - сохранение в список.
А как сделать обратную операцию? То есть чтобы была обычная древовидная структура JSON в переменной.

Разные вариации типа:
C#:
Развернуть Свернуть Копировать
Dictionary<string, string> str = Global.ZennoLab.Json.JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
return Global.ZennoLab.Json.JsonConvert.SerializeObject(str);
не помогают.

SOLVED
 
Последнее редактирование:
Метод через рекурсию. Слишком большой json, думаю, не стоит использовать.
Просто выводит всех потомков.
Для использования нужно править под себя.

В общий код:
Развернуть Свернуть Копировать
public static void jsnMembers ( IZennoPosterProjectModel  project, dynamic json ) {
  
    List<string> members = json.GetMembersList();
      foreach (string member in members) {
        try {
       project.SendInfoToLog( member );
          jsnMembers( project, json.GetMember( member  ));
        }
    catch (Exception e ) {
     //"------next element--------" ;
       }
    }
   }

Вызываем:
C#:
Развернуть Свернуть Копировать
CC.jsnMembers(project, project.Json);

Почему-то ошибка в этой строке общего кода
В общий код:
Развернуть Свернуть Копировать
public static void jsnMembers ( IZennoPosterProjectModel  project, dynamic json )
 

Кто просматривает тему: (Всего: 0, Пользователи: 0, Гости: 0)