c++ - partir - Analizar atributos XML con Boost
schema dtd xml (2)
El problema con su programa se encuentra en esta línea:
const ptree & attributes = formats.get_child(at, empty_ptree());
Con esta línea, usted está pidiendo que la pet.<xmlattr>
del niño pet.<xmlattr>
de las pets
y lo hace 3 veces independientemente de la que esté atravesando. Siguiendo este artículo , supongo que lo que necesitas usar es:
const ptree & attributes = f.second.get_child("<xmlattr>", empty_ptree());
El código completo, que funciona con ambos archivos xml, es:
#define ATTR_SET ".<xmlattr>"
#define XML_PATH1 "./pets.xml"
#include <iostream>
#include <string>
#include <boost/foreach.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
using namespace std;
using namespace boost;
using namespace boost::property_tree;
const ptree& empty_ptree(){
static ptree t;
return t;
}
int main() {
ptree tree;
read_xml(XML_PATH1, tree);
const ptree & formats = tree.get_child("pets", empty_ptree());
BOOST_FOREACH(const ptree::value_type & f, formats){
string at = f.first + ATTR_SET;
const ptree & attributes = f.second.get_child("<xmlattr>", empty_ptree());
cout << "Extracting attributes from " << at << ":" << endl;
BOOST_FOREACH(const ptree::value_type &v, attributes){
cout << "First: " << v.first.data() << " Second: " << v.second.data() << endl;
}
}
}
Me gustaría compartir con ustedes un problema que tengo al intentar procesar algunos atributos de elementos XML en C ++ con las bibliotecas Boost (versión 1.52.0). Dado el siguiente código:
#define ATTR_SET ".<xmlattr>"
#define XML_PATH1 "./pets.xml"
#include <iostream>
#include <string>
#include <boost/foreach.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
using namespace std;
using namespace boost;
using namespace boost::property_tree;
const ptree& empty_ptree(){
static ptree t;
return t;
}
int main() {
ptree tree;
read_xml(XML_PATH1, tree);
const ptree & formats = tree.get_child("pets", empty_ptree());
BOOST_FOREACH(const ptree::value_type & f, formats){
string at = f.first + ATTR_SET;
const ptree & attributes = formats.get_child(at, empty_ptree());
cout << "Extracting attributes from " << at << ":" << endl;
BOOST_FOREACH(const ptree::value_type &v, attributes){
cout << "First: " << v.first.data() << " Second: " << v.second.data() << endl;
}
}
}
Digamos que tengo la siguiente estructura XML:
<?xml version="1.0" encoding="utf-8"?>
<pets>
<cat name="Garfield" weight="4Kg">
<somestuff/>
</cat>
<dog name="Milu" weight="7Kg">
<somestuff/>
</dog>
<bird name="Tweety" weight="0.1Kg">
<somestuff/>
</bird>
</pets>
Por lo tanto, la salida de la consola que obtendré será la siguiente:
Extracting attributes from cat.<xmlattr>:
First: name Second: Garfield
First: weight Second: 4Kg
Extracting attributes from dog.<xmlattr>:
First: name Second: Milu
First: weight Second: 7Kg
Extracting attributes from bird.<xmlattr>:
First: name Second: Tweety
First: weight Second: 0.1Kg
Sin embargo, si decido usar una estructura común para cada elemento individual que se establece desde el nodo raíz (para identificarlos a partir de sus atributos específicos), el resultado cambiará por completo. Este puede ser el archivo XML en tal caso:
<?xml version="1.0" encoding="utf-8"?>
<pets>
<pet type="cat" name="Garfield" weight="4Kg">
<somestuff/>
</pet>
<pet type="dog" name="Milu" weight="7Kg">
<somestuff/>
</pet>
<pet type="bird" name="Tweety" weight="0.1Kg">
<somestuff/>
</pet>
</pets>
Y la salida sería la siguiente:
Extracting attributes from pet.<xmlattr>:
First: type Second: cat
First: name Second: Garfield
First: weight Second: 4Kg
Extracting attributes from pet.<xmlattr>:
First: type Second: cat
First: name Second: Garfield
First: weight Second: 4Kg
Extracting attributes from pet.<xmlattr>:
First: type Second: cat
First: name Second: Garfield
First: weight Second: 4Kg
Parece que el número de elementos que cuelgan del nodo raíz se reconoce correctamente ya que se han impreso tres conjuntos de atributos. Sin embargo, todos ellos se refieren a los atributos del primer elemento ...
No soy un experto en C ++ y soy realmente nuevo en Boost, así que esto podría ser algo que me falta con respecto al procesamiento de mapeo de hash o algo así ... Cualquier consejo será muy apreciado.
Sin usar esta función hasta ahora, sospecho que boost::property_tree
XML parser no es un analizador XML común, pero espera un determinado esquema, donde tiene exactamente una etiqueta específica para una propiedad específica.
Es posible que prefiera usar otros analizadores XML que proporcionen el análisis de cualquier esquema XML, si desea trabajar con XML más allá de las capacidades boost::property_tree
. Echa un vistazo a, por ejemplo, Xerces C ++ o Poco XML .