2011-01-04 8 views
14

Lo siento, hice una pregunta sobre el mismo tema anteriormente, pero mi problema se refiere a otro aspecto del descrito allí (How to iterate a boost...).Aumente los iteradores de Property_Tree, cómo manejarlos?

Tome un vistazo al siguiente código:

#include <iostream> 
#include <string> 
#include <boost/property_tree/ptree.hpp> 
#include <boost/property_tree/xml_parser.hpp> 
#include <boost/algorithm/string/trim.hpp> 
int main(int argc, char** argv) { 
    using boost::property_tree::ptree; 
    ptree pt; 
    read_xml("try.xml", pt); 
    ptree::const_iterator end = pt.end(); 
    for (ptree::const_iterator it = pt.begin(); it != end; it++) 
      std::cout << "Here " << it->? << std::endl; 
} 

Bueno, como me dijeron dicho en la pregunta que he mencionado, existe la posibilidad de usar iteradores en property_tree en Boost, pero yo no sé qué escriba qué es y qué métodos o propiedades puedo usar.

Bueno, supongo que debe ser otro ptree o algo que representa otra jerarquía xml para ser examinado de nuevo (si quiero) pero la documentación sobre esto es muy mala. No sé por qué, pero en los documentos de impulso no puedo encontrar nada bueno, solo algo sobre una macro para explorar nodos, pero este enfoque es uno que realmente me gustaría evitar.

Por lo tanto, para llegar a mi pregunta aquí: una vez que obtenga el iterador en un ptree, ¿cómo puedo acceder al nombre del nodo, valor, parámetros (un nodo en un archivo xml)? Gracias

Respuesta

18

Estoy de acuerdo con Andry, y encontrar la documentación de property_tree a ser extremadamente mínimas en lo más mínimo. Necesitaba un preeree para cargar objetos idénticos con configuraciones diferentes, y tenía problemas para averiguar sobre qué itera el iterador, qué tipo devuelve y si permanecerá o no en el nivel de objetos, o ir a través de cada nodo como BFS. Por último, me las arreglé para conseguir mi código de trabajo para un caso similar al siguiente: El archivo

ajustes:

<object1> 
    <enable>true</enable> 
    <label>hello</label> 
</object1> 
<object2> 
    <enable>false</enable> 
    <label>goodbye</label> 
</object2> 

En primer lugar, he añadido un constructor para mi objeto, que puede inicializar en un ptree.Tenga en cuenta que estoy usando el conseguir con la opción por defecto, para evitar una excepción en Get fallado() 's:

object::object(const boost::property_tree::ptree &pt_) 
{ 
    enable = pt_.get<bool>("enable", true); // usage is: get<type>(path, default) 
    label = pt_.get<std::string>("label", "empty"); 
} 

fin el siguiente código carga ambos objetos, y los coloca en un mapa:

std::map<std::string, my_object> objects_map; 

// parse settings file and add loggers 
if(filesystem::exists(logger_settings_file)) 
{ 
    boost::property_tree::ptree pt; 

    read_xml(logger_settings_file, pt); 
    BOOST_FOREACH(boost::property_tree::ptree::value_type &v, pt) 
    { 
     objects_map[v.first] = my_object(v.second); 
    } 
} 

por lo tanto, para responder a mis propias preguntas:

  • se repite el iterador sobre el archivo de configuración sin caer en los niveles más bajos. Ejecutando el código anterior, encontrará que el ciclo itera dos veces, una vez para cada objeto en el archivo XML.
  • El iterador devuelve un objeto value_type que se asemeja a un par, y tiene los accesos first y second. v.first es std :: string que contiene el nodo padre (en mi caso "object1", "object2"), y v.second es un boost::property_tree::ptree, que se puede usar para analizar los campos del objeto.
+0

Gracias bavaza ... tu respuesta explicó un mejor enfoque ... Me gustó. Gracias – Andry

+0

@Andry. Salud. – bavaza

0

Debe tener los conocimientos previos en el archivo de propiedades de entrada.

Árbol de propiedades Boost no es un analizador de documentos general. Hará un análisis sintáctico y dará acceso a los datos, pero debe ubicarlo manualmente.

No sé si hay un método para navegar por el documento completo, pero si solo necesita las propiedades de su propio archivo, puede hacerlo con un código muy simple.

Desde el boost documentation:

1) La versión de lanzamiento (conseguir):

ptree pt; 
/* ... */ 
float v = pt.get<float>("a.path.to.float.value"); 

2) La versión de valor por defecto (GET):

ptree pt; 
/* ... */ 
float v = pt.get("a.path.to.float.value", -1.f); 

3) La opcional versión (get_optional):

ptree pt; 
/* ... */ 
boost::optional<float> v = pt.get_optional<float>("a.path.to.float.value"); 
19

de impresión completa del árbol:

void print(boost::property_tree::ptree const& pt) 
{ 
    using boost::property_tree::ptree; 
    ptree::const_iterator end = pt.end(); 
    for (ptree::const_iterator it = pt.begin(); it != end; ++it) { 
     std::cout << it->first << ": " << it->second.get_value<std::string>() << std::endl; 
     print(it->second); 
    } 
} 
+0

Hola, acabo de rechazar una edición anónima en esta publicación (ya que cambia tu código). Es posible que desee [verifíquelo] (http://stackoverflow.com/suggested-edits/264840) para ver si debe ser incorporado a su respuesta. – Benjol

+0

@Benjol: tnx. Estuvo bien, así que lo incorporé. –

Cuestiones relacionadas