c++ xml boost

c++ - Uso de Boost para leer y escribir archivos XML



(15)

¿Hay alguna manera buena (y también sencilla) de utilizar Boost para leer y escribir archivos XML?

Parece que no puedo encontrar ninguna muestra simple para leer archivos XML usando Boost. ¿Puede indicarme una muestra simple que usa Boost para leer y escribir archivos XML?

Si no es Boost, ¿hay alguna biblioteca buena y simple para leer y escribir archivos XML que pueda recomendar? (debe ser una biblioteca de C ++)


¿Qué pasa con boost.spirit?

Here , muestran un analizador " Mini XML "


Boost no proporciona una memoria caché de analizador XML.

Poco XML (parte de las librerías Poco C ++ ) es bueno y simple.


Bueno, no hay una biblioteca específica para el análisis de XML, pero hay muchas alternativas, aquí hay una pareja: libxml , Xerces , Expat

Por supuesto, podría utilizar algunas de las otras bibliotecas para ayudarlo a crear su propia biblioteca, pero eso probablemente sea una empresa.

Y aquí hay un artículo completo sobre el tema de IBM.


Deberías probar pugixml Analizador de XML ligero, simple y rápido para C ++

Lo mejor de pugixml es el soporte de XPath , del que carecen TinyXML y RapidXML.

Citando al autor de RapidXML "Me gustaría agradecer a Arseny Kapoulkine por su trabajo en pugixml, que fue una inspiración para este proyecto" y "5% - 30% más rápido que pugixml, el analizador de XML más rápido que conozco" Había probado con la versión 0.3 de pugixml, que ha llegado recientemente a la versión 0.42.

Aquí hay un extracto de la documentación pugixml:

Las principales características son:

  • bajo consumo de memoria y fragmentación (la ganancia sobre pugxml es ~ 1.3 veces, TinyXML - ~ 2.5 veces, Xerces (DOM) - ~ 4.3 veces 1). Los números exactos se pueden ver en Comparación con la sección de analizadores existente.
  • velocidad de análisis extremadamente alta (la ganancia sobre pugxml es ~ 6 veces, TinyXML - ~ 10 veces, Xerces-DOM - ~ 17.6 veces 1
  • velocidad de análisis extremadamente alta (bueno, me estoy repitiendo, pero es tan rápido que supera a Expat en 2,8 veces en el XML de prueba) 2
  • más o menos conforme al estándar (analizará correctamente cualquier archivo que cumpla con los estándares, con la excepción de los problemas relacionados con DTD)
  • casi ignorante de errores (no se ahogará en algo como You & Me, como expat will; analizará archivos con datos con codificación incorrecta, y así sucesivamente)
  • interfaz limpia (una pugxml fuertemente refactorizada)
  • más o menos consciente de Unicode (en realidad, asume la codificación UTF-8 de los datos de entrada, aunque funcionará fácilmente con ANSI - no hay UTF-16 por ahora (ver Trabajo futuro), con funciones de conversión de ayuda (UTF-8 <- > UTF-16/32 (lo que sea predeterminado para std :: wstring & wchar_t))
  • Código C ++ totalmente compatible (aprobado por el modo estricto de Comeau); la biblioteca es multiplataforma (ver referencia para la lista de plataformas)
  • alta flexibilidad. Puede controlar muchos aspectos del análisis de archivos y la creación de árbol DOM a través de las opciones de análisis.

De acuerdo, podrías preguntar: ¿cuál es el truco? Todo es muy lindo, es una solución pequeña, rápida, robusta y limpia para analizar XML. ¿Lo que falta? Ok, somos desarrolladores justos, así que aquí hay una lista de errores:

  • consumo de memoria Es mejor que todos los analizadores basados ​​en DOM que conozco, pero cuando llega el analizador de SAX, no hay posibilidad. No puede procesar un archivo XML de 2 Gb con menos de 4 Gb de memoria, y hágalo rápidamente. Aunque pugixml se comporta mejor que cualquier otro analizador basado en DOM, por lo que si estás atascado con DOM, no es un problema.
  • consumo de memoria Ok, me estoy repitiendo a mí mismo. De nuevo. Cuando otros analizadores le permitan proporcionar un archivo XML en un almacenamiento constante (o incluso como un área de memoria asignada), pugixml no lo hará. Por lo tanto, deberá copiar los datos completos en un almacenamiento no constante. Además, debería persistir durante la vida del analizador (las razones para eso y más sobre la duración de la vida están escritas a continuación). De nuevo, si está bien con DOM, no debería ser un problema, ya que el consumo general de memoria es menor (bueno, aunque necesitará un trozo contiguo de memoria, lo que puede ser un problema).
  • falta de validación, procesamiento DTD, espacios de nombres XML, manejo adecuado de la codificación. Si los necesita, vaya a tomar MSXML o XercesC o algo por el estilo.

Definitivamente, use TinyXML * up-up *




Parece que la serialización boost puede leer y escribir archivos en XML, si eso es suficiente para sus propósitos.

XML más fácil con Boost


Según mis experiencias al acecho en la lista de correo de Boost, parece que cada vez que XML aparece como un tema, se desvía a una discusión sobre Unicode. Sin embargo, dado que existe una posible biblioteca Unicode en este momento, no creo que tarde demasiado tiempo en aparecer una biblioteca XML.

Mientras tanto, yo también he estado usando TinyXML.

Interesante enlace sobre RapidXML. Echaré un vistazo a eso.


Si solo está buscando la funcionalidad DOM, ya hay algunas sugerencias en este hilo. Personalmente, probablemente no me molestaría con una biblioteca que carezca de soporte XPath, y en C ++, usaría Qt. También está TinyXPath, y Arábica afirma tener soporte XPath, pero no puedo decir nada sobre eso.


También está TinyXML , que es una pequeña y agradable biblioteca de C ++. Si está buscando una biblioteca de nivel inferior, RapidXML es un excelente punto de partida.


Una advertencia. Me encanta RapidXML, pero tiene un error muy desagradable al analizar UTF16. Algunos valores válidos hacen que se bloquee.

Me encantaría recomendar pugixml, pero carece de soporte de espacio de nombres, lo que sé que me causará problemas.



Boost usa RapidXML como se describe en el capítulo Analizador XML de la página Cómo completar un árbol de propiedades :

Lamentablemente, no hay ningún analizador XML en Boost en el momento de escribir esto. Por lo tanto, la biblioteca contiene el rápido y pequeño analizador RapidXML (actualmente en la versión 1.13) para proporcionar soporte de análisis XML. RapidXML no es completamente compatible con el estándar XML; no es capaz de analizar las DTD y, por lo tanto, no puede hacer una sustitución completa de la entidad.

Consulte también el tutorial XML boost .

Como el OP quiere una "forma simple de usar boost para leer y escribir archivos xml" , proporciono a continuación un ejemplo muy básico:

<main> <owner>Matt</owner> <cats> <cat>Scarface Max</cat> <cat>Moose</cat> <cat>Snowball</cat> <cat>Powerball</cat> <cat>Miss Pudge</cat> <cat>Needlenose</cat> <cat>Sweety Pie</cat> <cat>Peacey</cat> <cat>Funnyface</cat> </cats> </main>

(Los nombres de los gatos son de la página de Matt Mahoney )

La estructura correspondiente en C ++:

struct Catowner { std::string owner; std::set<std::string> cats; };

read_xml() :

#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/xml_parser.hpp> Catowner load(const std::string &file) { boost::property_tree::ptree pt; read_xml(file, pt); Catowner co; co.owner = pt.get<std::string>("main.owner"); BOOST_FOREACH( boost::property_tree::ptree::value_type &v, pt.get_child("main.cats")) co.cats.insert(v.second.data()); return co; }

write_xml() :

void save(const Catowner &co, const std::string &file) { boost::property_tree::ptree pt; pt.put("main.owner", co.owner); BOOST_FOREACH( const std::string &name, co.cats) pt.add("main.cats.cat", name); write_xml(file, pt); }


<?xml version="1.0"?> <Settings> <GroupA> <One>4</One> <Two>7</Two> <Three>9</Three> </GroupA> <GroupA> <One>454</One> <Two>47</Two> <Three>29</Three> </GroupA> <GroupB> <A>String A</A> <B>String B</B> </GroupB> </Settings>

Hay una manera fácil de leer XML con BOOST. Este ejemplo está basado en std :: wstring:

#include <string> #include <boost/property_tree/xml_parser.hpp> #include <boost/property_tree/ptree.hpp> #include <boost/foreach.hpp> bool CMyClass::ReadXML(std::wstring &full_path) { using boost::property_tree::wptree; // Populate tree structure pt: wptree pt; std::wstringstream ss; ss << load_text_file(full_path); // See below for ref. read_xml(ss, pt); // Traverse pt: BOOST_FOREACH(wptree::value_type const& v, pt.get_child(L"Settings")) { if (v.first == L"GroupA") { unsigned int n1 = v.second.get<unsigned int>(L"One"); unsigned int n2 = v.second.get<unsigned int>(L"Two"); unsigned int n3= v.second.get<unsigned int>(L"Three"); } else if (v.first == L"GroupB") { std::wstring wstrA = v.second.get<std::wstring>(L"A"); std::wstring wstrB = v.second.get<std::wstring>(L"B"); } }; }

Leer atributos es un poco más complicado.

-

Solo para la referencia:

std::wstring load_text_file(std::wstring &full_path) { std::wifstream wif(full_path); wif.seekg(0, std::ios::end); buffer.resize(wif.tellg()); wif.seekg(0); wif.read(buffer.data(), buffer.size()); return buffer; }