Проблемы с деревом свойств Boost и синтаксическим анализом Xml
-
22-09-2019 - |
Вопрос
Я использую boost::property_tree
.Документация очень расплывчата и в целом по большей части бесполезна.Просмотр источника / примеров тоже не очень помог.
Что меня интересует, так это следующее:
<VGHL>
<StringTable>
<Language>EN</Language>
<DataPath>..\\Data\\Resources\\Strings\\stringtable.bst</DataPath>
</StringTable>
</VGHL>
Как я могу выполнить итерацию по всем элементам на текущем уровне?Если я сделаю это:
read_xml(fin, bifPropTree);
VGHL::String tablePath;
BOOST_FOREACH(boost::property_tree::wiptree::value_type &v,
bifPropTree.get_child(L"VGHL.StringTable"))
{
m_StringTable->ParseEntry(v.second, tablePath);
}
В ParseEntry
Я пробую это:
VGHL::String langName = stringTree.get<VGHL::String>(L"StringTable.Language");
Приводит к исключению (not не существует).Я тоже пробовал это:
VGHL::String langName = stringTree.get<VGHL::String>(L"Language");
Та же проблема.
Из моего понимания, когда я звоню ParseEntry
Я передаю ссылку на дерево в этом узле.
Есть ли какой-нибудь способ справиться с этим, когда у меня есть несколько записей StringTable
используя дерево свойств?
Решение
ParseEntry получает ссылку на каждый из дочерних узлов текущего уровня.Таким образом, вы не можете запрашивать значения, используя имя узла, потому что у вас уже есть дочерний узел.Имя узла хранится в v.первый.
Вы можете выполнить итерацию по всем элементам на заданном уровне, используя получить_child чтобы выбрать уровень, а затем BOOST_FOREACH УСКОРЕНИЕ_ДОХОДА для повторения.Каждый итератор будет представлять собой пару, представляющую имя узла и данные узла:
using boost::property_tree::wiptree;
wiptree &iterationLevel = bifPropTree.get_child(L"VGHL.StringTable");
BOOST_FOREACH(wiptree::value_type &v, iterationLevel)
{
wstring name = v.first;
wstring value = v.second.get<wstring>(L"");
wcout << L"Name: " << name << L", Value: " << value.c_str() << endl;
}
Этот код будет печатать:
Имя:Язык, Значение:EN
Имя:Путь к данным, Значение:..\\Данные\\Ресурсы\\Строки\\stringtable.bst
Если вы не хотите выполнять итерацию, вы можете выбрать уровень узла, а затем выполнить поиск узлов по их названию:
wiptree &iterationLevel = bifPropTree.get_child(L"VGHL.StringTable");
wstring valueLang = iterationLevel.get<wstring>(L"Language");
wstring valuePath = iterationLevel.get<wstring>(L"DataPath");
wcout << valueLang << endl << valuePath << endl;
Этот код будет печатать:
EN
..\\Данные\\Ресурсы\\Строки\\stringtable.bst
Другие советы
Я не использовал дерево свойств, но, вероятно, буду использовать, так как оно выглядит изящно.Однако несколько быстрых замечаний:
Разве параметр шаблона get не должен совпадать с типом возвращаемого значения?
VGHL::String langName = stringTree.get(...);
Но здесь, скорее всего, это не проблема, так как это привело бы к ошибке во время компиляции.
Не уверен, работает ли аргумент L "VGHL.StringTable.Language"?