Не удалось объединить входную строку для получения значения JSON ... но можно жестко ее кодировать - PullRequest
1 голос
/ 20 июня 2019

Я пытаюсь перебрать список объектов в JSON, чтобы найти объект с соответствующим KVP (в C ++ с использованием RapidJSON).Мне удалось получить значение с помощью жестко закодированного указателя, но я не могу заставить функцию GetValueByPointer(document, "PointerString") принять динамическую строку, которую я строю.

JSON выглядит так:

{ "_id" : { "$oid" : "5d0985973f1c0000ee000000" }, 
"Location" : [ { "lat" : "39.4005", "lon" : "-106.106"} ], 
"Weather" : [ { "timestamp" : "2019-06-05T00:00:00", ...}, { "timestamp" : "2019-06-05T01:00:00", ...}}

Это работает:

Document document;
document.Parse(json);
Value* a = GetValueByPointer(document, "/Weather/1/timestamp");
std::cout << a->GetString() << std::endl;

Это не работает:

Value* a = GetValueByPointer(document, "/Weather/1/timestamp");
int i = 1;
std::string base = "/Weather/";
std::string tail = "/timestamp"; 
std::string PointerString;
std::string TSString = "";

while(TSString != "2019-06-05T09:00:00") {
    PointerString=base;
    PointerString.append(std::to_string(i));
    PointerString.append(tail);
    PointerString = "\"" + PointerString + "\"";

    Value* timestamp = GetValueByPointer(document, PointerString);
    TSString = timestamp->GetString();
    std::cout << TSString << std::endl;
    i++;
} 

Я получаю сообщение об ошибке, независимо от того, во что я пытаюсь конвертировать PointerString:

/usr/local/include/rapidjson/pointer.h:1156:30: note:   template argument deduction/substitution failed:
MGOIO.cc:145:62: note:   mismatched types ‘const CharType [N]’ and ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’
  Value* timestamp = GetValueByPointer(document, PointerString);
                                                              ^

Когда я вывожу PointerString на экран, это выглядит хорошо для меня:

"/Weather/1/timestamp"

Любая помощь очень ценится!

Ответы [ 2 ]

1 голос
/ 20 июня 2019

Я решил это, переключившись на nlohmann JSON.Поскольку указатель nlohmann создан для приема строки, это было очень просто.Я заменил JSON здесь для того, как я получаю свой JSON.

#include <iostream>
#include <string>
#include <fstream>
#include <nlohmann/json.hpp>

using json = nlohmann::json;

json j = json::parse(JSON);

int i = 0;
int k;
std::string base = "/Weather/";
std::string tail = "/timestamp"; 
std::string PointerString;
std::string TSString = "";

while(TSString != "2019-06-05T09:00:00") {
        PointerString=base;
        PointerString.append(std::to_string(i));
    PointerString.append(tail);
    json::json_pointer p1(PointerString);
    TSString = j.at(p1);
        std::cout << TSString << std::endl;
    std::cout << i << std::endl;
    k=i;
    i++;
} 
0 голосов
/ 20 июня 2019

Если вы посмотрите на Pointer.h, вы увидите различные шаблонные определения GetValueByPointer().

template <typename T>
 typename T::ValueType* GetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {
     return pointer.Get(root, unresolvedTokenIndex);
 }

 template <typename T>
 const typename T::ValueType* GetValueByPointer(const T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {
     return pointer.Get(root, unresolvedTokenIndex);
 }

 template <typename T, typename CharType, size_t N>
 typename T::ValueType* GetValueByPointer(T& root, const CharType (&source)[N], size_t* unresolvedTokenIndex = 0) {
     return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
 }

 template <typename T, typename CharType, size_t N>
 const typename T::ValueType* GetValueByPointer(const T& root, const CharType(&source)[N], size_t* unresolvedTokenIndex = 0) {
     return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
 }

Теперь вы надеетесь на неявное преобразование типов из std::string -> GenericPointer<...>, которое не произойдет из-за правила C ++, что допускается не более 1 неявного преобразования типов. Здесь вам понадобится std::string -> const CharType(&source)[N] -> GenericPointer<...>, что является одним неявным преобразованием слишком много.

Я думаю, что самым простым способом исправить ваше затруднительное положение было бы то, что вы написали свою собственную версию этой функции (как вы, вероятно, будете вызывать ее пару раз), конечно же, с шаблонами, как и другие, и которая требует const std::string & или const std::basic_string<CharType>& и выполните преобразование явно.

Это, плюс удаление строки, о которой я упоминал в своем комментарии, должно работать.

...