无法连接输入字符串以检索JSON值...但是可以对其进行硬编码

时间:2019-06-20 00:36:00

标签: c++ rapidjson

我正在尝试遍历JSON中的对象列表,以找到具有匹配KVP的对象(在使用RapidJSON的C ++中)。我设法使用硬编码的指针来检索值,但是无法获取函数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 个答案:

答案 0 :(得分:1)

我通过切换到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++;
} 

答案 1 :(得分:0)

如果您查看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<...>,这是太多的隐式转换。

我认为,解决困境的最简单方法是编写此函数的自己的版本(可能会多次调用),当然要以其他模板为模板,并且需要{{1} }或const std::string &并明确进行转换。

那,加上删除我在评论中提到的行也应该起作用。