Для Boost.Propertytree, есть ли способ использовать нотацию JSON для ссылки на элемент массива? - PullRequest
1 голос
/ 21 июня 2019

Было бы замечательно иметь возможность указать путь в Boost.PropertyTree, содержащем массив.

Я могу создать Boost.PropertyTree из этого JSON:

const char* theJSONTestText = R"FooArrayTest({
    "FooArray": [
                 {"BarIntValue": 10, "BarString": "some string"},
                 {"BarIntValue": 99, "BarString": "another string"},
                 {"BarIntValue": 45, "BarString": "a third string"}
    ]
})FooArrayTest";

Который построен и печатается, как и ожидалось:

FooArray: 
: 
BarIntValue: 10
BarString: some string
: 
BarIntValue: 99
BarString: another string
: 
BarIntValue: 45
BarString: a third string

Конечно, отдельные элементы массива не имеют имен.

Я знаю, КАК перебирать свойство FooArray, но было бы особенно удобно иметь возможность доступа к отдельным элементам через путь точечной нотации JSON, например, "FooArray [2] .BarString", для доступа к полю в третьей элемент массива:

std::string theSecondBarString = theParsedTree.get<std::string>("FooArray[2].BarString");

Конечно, это вызывает исключение, потому что я предполагаю, что Boost.PropertyTree не знает, как обрабатывать путь со спецификатором массива? Или у меня неверный синтаксис?

ПОЧЕМУ Я ХОЧУ ДЕЛАТЬ ЭТОТ ПУТЬ?

Я хочу, чтобы клиент этого PropertyTree мог не только получать данные из определенного элемента массива, но также и SET (т.е. изменять) данные определенного элемента массива. Если нет прямой записи пути, тогда клиент должен использовать мои изобретенные API-функции, чтобы сначала извлечь, а затем получить доступ к нужному полю, и наоборот, чтобы выписать его обратно. Это может быть утомительно и подвержено ошибкам для узлов дерева, которые содержат элементы массива в элементах массива.

1 Ответ

0 голосов
/ 22 июня 2019

Невероятно -

Этот синтаксис создает именно то, что я ищу:

const char* theJSONTestText = R"FooArrayTest({
    "SomeArray": {
        "[1]":  {"BarIntValue": 10, "BarString": "some string"},
        "[2]":  {"BarIntValue": 99, "BarString": "another string"},
        "[3]": {"BarIntValue": 45, "BarString": "a third string"}
    }
})FooArrayTest";

... который создает PropertyTree следующим образом:

DUMP OF parsed JSON:
SomeArray: 
[1]: 
BarIntValue: 10
BarString: some string
[2]: 
BarIntValue: 99
BarString: another string
[3]: 
BarIntValue: 45
BarString: a third string

... и допускает синтаксис, такой как:

std::string theSecondBarString = theParsedTree.get<std::string>("SomeArray.[2].BarString");

... и - ВОЙЛА:

Second bar string = another string

ВАЖНО: необходимо отметить, что при таком подходе нотация массива "[", "]" в исходном тексте определения JSON отсутствует. Вместо этого я просто создаю ДЕТСКИЕ УЗЛЫ SomeArray с именами "[n]". Каждый дочерний узел ([1], [2], [3]) имеет свои собственные дочерние узлы с BarIntValue и BarString. Не то, что я ожидал, но это работает!

Теперь мне просто нужно выяснить, как сконструировать это PropertyTree, используя функции-члены (вместо необработанного JSON), и я - золото!

...