2012-06-15 18 views
5

Come rimuoveresti un nodo dall'albero delle proprietà boost xml?Albero proprietà Boost: rimuovi un nodo

Ho un documento come questo:

<folders> 
    <folder>some/folder</folder> 
    <folder>some/folder</folder> 
    <folder>some/folder</folder> 
</folders> 

so come itereate e stampare tutte le cartelle, ma come faccio a rimuovere una delle voci e salvare il xml indietro?

risposta

0

Beh, ho fatto in questo modo:

void Backups::removeGeneric(const std::string key, const std::string value) 
{ 
    boost::property_tree::ptree pt; 
    boost::property_tree::xml_parser::read_xml(Backups::getBackupFile(), pt); 

    bool remove = true; 

    try { 
     pt.get_child(key); 
    } 
    catch(boost::exception &ex) 
    { 
     std::cout << "There is nothing to remove." << std::endl; 
     remove = false; 
    } 

    if(remove) 
    { 
     bool exists = false; 

     boost::property_tree::ptree newPt; 

     BOOST_FOREACH(boost::property_tree::ptree::value_type &v, pt.get_child(key)) 
     { 
      if(v.second.data() != value) 
       newPt.add("scheme", v.second.data()); 

      if(v.second.data() == value) 
       exists = true; 
     } 

     if(exists) 
     { 
      pt.put_child(key, newPt); 
      boost::property_tree::xml_parser::write_xml(Backups::getBackupFile(), pt); 

      std::cout << value << " was removed." << std::endl; 
     } 
     else 
      std::cout << value << " is not added." << std::endl; 
    } 
} 
+2

Non usare eccezioni per il controllo del flusso. – CaffeineAddict

2
void Backups::removeGeneric(const std::string key, const std::string value) 
{ 
    typedef boost::property_tree::ptree Tree; 

    Tree pt; 
    boost::property_tree::xml_parser::read_xml(Backups::getBackupFile(), pt); 

    std::pair< Tree::assoc_iterator, Tree::assoc_iterator> range = pt.equal_range(key); 
    if(range.first == pt.not_found()) 
    { 
     std::cout << "There is nothing to remove." << std::endl; 
    } 
    else 
    { 
     bool removed = false; 

     do 
     { 
      if(assoc_i->second.data() == value) { 
       Tree::iterator i = pt.to_iterator(assoc_i); 
       pt.erase(i); 
       removed = true; 
       // not sure if this is completely necessary - trying 
       // to guard against invalidating the iterator 
       // via erase - if removed, remember to ++i! 
       range = pt.equal_range(key); 
       i = range.first; 
      } 
      else 
       ++i; 
     } while(i != pt.not_found()); 

     if(removed) 
     { 
             boost::property_tree::xml_parser::write_xml(Backups::getBackupFile(), pt); 
      std::cout << value << " was removed." << std::endl; 
     } 
     else 
      std::cout << value << " is not added." << std::endl; 
    } 
} 
4

mi sarebbe probabilmente provare:

boost::property_tree::ptree pt; 

pt.erase(key); 
+5

Questo eliminerà la prima chiave, non una chiave specifica .-- questo è un problema se l'albero figlio contiene più di una chiave con lo stesso nome. –

0
// Recursively erase nodes 
    void prune_nodes(ptree& Prop_tree, const char* Node_name) 
    { 
     ptree::iterator Root = Prop_tree.begin(); // Node iterator 
     ptree::iterator End = Prop_tree.end(); // Stop sentinel 
     // Loop through current 'Root-Level' 
     for(Root; Root != End; Root++) 
     { 
      Root->second.erase(Node_name); // Erase nodes in current 'Root-Level' sub-tree 
      prune_nodes(Root->second, Node_name); // Recurse using current sub-tree as next call's ptree 
     } 
    } 
Problemi correlati