Повысить дерево свойств: удалить узел, используя указатели на узел и его родительский узел

Я хочу удалить узел из дерева, который основан на XML:

<library>
    <booklist>
        <book id="10">
            <data title="t1"/>
        </book>
        <book id="10">
            <data title="t2"/>
        </book>
        <book id="10">
            <data title="t3"/>
        </book>
        <book id="20">
            <data title="t4"/>
        </book>
    </booklist>
</library>

У меня есть алгоритм, чтобы найти правильный узел, который возвращает указатель на удаляющий узел. Также у меня есть указатель на родителя удаляющего узла. но erase() будет использовать итератор (не указатель). Мой вопрос заключается в том, как удалить узел, используя два указателя; указатель на удаляющий узел и другой на родительский узел.

void removeElement(const std::string addr, const std::string criteria, boost::property_tree::ptree &ptSource)
{
    boost::property_tree::ptree *ptParent = findParentPTree(addr, criteria, ptSource);   // Points to "library.booklist"
    boost::property_tree::ptree *ptRemove = findRemovePTree(addr, criteria, ptSource);   // eg the third <book> which contains the <data title="t3"/>

    // question: how to remove node ptRemove from ptSource?
}

Обратите внимание, что есть несколько примеров использования итераторов, но не ясно, как найти итератор удаления узла.

1 ответ

Решение

Действительно, нет прямой функции, чтобы получить итератор из ссылки на значение. Поэтому вам придется написать это самостоятельно:

В этом случае может показаться, что он не нужен для рекурсии, поэтому все проще:

Жить на Колиру

#include <iostream>
#include <boost/property_tree/ptree.hpp>

using namespace boost::property_tree;

ptree::iterator child_iterator(ptree& within, ptree const& child) {
    for (auto it = within.begin(); it != within.end(); ++it)
        if (std::addressof(it->second) == std::addressof(child))
            return it;

    return within.end();
}

ptree* findParentPTree(std::string const, std::string const&, ptree const&);
ptree* findRemovePTree(std::string const, std::string const&, ptree const&);

void removeElement(const std::string& addr, const std::string& criteria, ptree &ptSource)
{
    ptree *ptParent = findParentPTree(addr, criteria, ptSource); // Points to "library.booklist"
    ptree *ptRemove = findRemovePTree(addr, criteria, ptSource); // eg the third <book> which contains the <data title="t3"/>

    auto it = child_iterator(*ptParent, *ptRemove);
    if (it != ptParent->end())
        ptParent->erase(it);
}
Другие вопросы по тегам