2016-03-02 5 views
0

У меня есть запись Json с вложенными объектами и объектными массивами, ключи в этом поле содержат пробелы, я хочу изменить все пробелы на _, поэтому мне нужно повторить все ключи в json object.rapidjson - рекурсивно изменить значение ключа с вложенным полем

Моя идея написать первый поиск глубины, чтобы перебрать все вложенные ключи, используя ConstMemberIterator, мой вопрос в том, как изменить ключ с помощью его итератора?

В приведенном ниже примере представляет свою идею:

void DFSReplaceSpaceInKeys(Value::ConstMemberIterator& itr) { 
    // Replace space in nested key 
    std::string s(itr->name.GetString()); 
    std::replace(s.begin(), s.end(), ' ', '_'); 
    // set new string to key 
    itr->name.SetString(s, ?.GetAllocator()); // <----- How can I get the document allocator? 
    std::cout << "new key: " << itr->name.GetString() << std::endl; 
    // recursive call in DFS 
    if (itr->value.GetType() == Type::kObjectType) { 
     DFSReplaceSpaceInKeys(itr->value.GetObject().MemberBegin()); 
    } 
} 

А Json запись пример:

{ 
    "a": {"b": [{"c": [...]}, {...}] 
} 

ответ

1

Вы можете передать аллокатор в качестве параметра. Я также думаю, что вам лучше передать Value& для представления узла.

void DFSReplaceSpaceInKeys(Value& value, Value::AllocatorType& allocator) { 
    if (value.IsObject()) { 
     for (Value::ConstMemberIterator itr = value.MemberBegin(); itr != MemberEnd(); ++itr) 
     { 
      // Modify itr->name here... 
      DFSReplaceSpaceInKeys(itr->value, allocator); 
     } 
    } 
    else if (value.IsArray()) { 
     for (Value::ConstIterator itr = value.Begin(); itr != value.End(); ++itr) 
      DFSReplaceSpaceInKeys(*itr, allocator); 
    } 
} 

// ... 
Document d; 
DFSReplaceSpaceInKeys(d, d.GetAllocator()); 

Если вам нужно только сделать задачу, как уже упоминалось, вы можете просто использовать SAX API, который может быть проще и быстрее. Проверьте пример capitalize.

0
rapidjson::Document::AllocatorType& allocator = doc.GetAllocator(); 
auto news_obj= news_info["news_feature"].GetObject(); 
auto title_keyword = news_obj.FindMember ("title_keyword"); 
if (title_keyword != news_obj.MemberEnd()) { 
    title_keyword->name.SetString ("title_keywords", allocator); 
}