2017-10-26 5 views
1

노드에 대한 포인터와 그 부모 노드를 사용하여 노드를 제거: 나는 XML을 기반으로하는 ptree에서 노드를 제거 할

<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()는 포인터가 아닌 반복자를 취한다. 제 질문은 두 개의 포인터를 사용하여 노드를 제거하는 방법입니다. 제거 노드에 대한 poiter와 부모 노드에 대한 poiter.

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? 
} 

반복기를 사용하는 몇 가지 예제가 있지만 노드를 제거하는 반복기가 어떻게 발견되는지는 분명하지 않습니다.

+0

Out-of-The-Box : ab 'ptree' 인터페이스를 싫어하지만 이와 비슷한 예제처럼 도메인 별 래퍼를 작성하십시오 : https://stackoverflow.com/questions/45198739/iterate-through-multilevel-boost-tree/45201583#45201583 – sehe

+0

최대의 관련성을 위해 여기에 XML 대신 간단하게 번역 된 샘플 JSON http://coliru.stacked-crooked.com/a/af72134e9c1a18ab – sehe

답변

1

실제로 값 참조에서 반복기를 가져 오는 직접 함수는 없습니다. 그래서 당신은 그것을 직접 작성해야합니다 : 당신이 그래서 재귀 적으로 필요하지 않은

그것이 나타납니다 간단 :

Live On Coliru

#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); 
} 
+0

감사합니다. 매우 잘 작동합니다. –