2008-11-19 15 views
14

He utilizado la serialización de refuerzo, pero esto no parece permitirme generar xml que se ajuste a un esquema particular, parece que su propósito era simplemente persistir el estado de una clase.¿Cuál es la forma más fácil de generar xml en C++?

Plataforma: Linux

¿Qué utilizan ustedes para generar NO analizar XML?

Hasta ahora voy por la ruta de Foredecker de simplemente generarlo yo mismo - no es un documento grande, pero realmente no debería tener tantos problemas para encontrar una biblioteca decente para generarlo correctamente.

En cuanto a boost, lo que me gustaría hacer es establecer los nombres de los nodos, establecer los atributos en mis nodos y deshacerme de toda la basura que viene con eso, ya que realmente no me importa acerca de tener que volver a colocar mi documento en esa clase.

+0

He usado [libxml ++] (http://libxmlplusplus.sourceforge.net/) para generar XML, pero no puedo garantizar que sea la manera más fácil. :-) –

Respuesta

10

Algunos me pueden declarar un hereje XML, pero una manera efectiva es simplemente generarlo con sus herramientas de salida de cadena favoritas (impresión, secuencias de salida, etc.); esto puede ir a un búfer o un archivo.

Una vez guardado, debe validar con un esquema antes de enviarlo y enviarlo.

Para uno de nuestros proyectos, tenemos un conjunto muy simple de plantillas para administrar etiquetas y atributos de inicio/finalización. Estos tienen un operador de salida de flujo. Esto hace que sea muy fácil generar el origen XML y la depuración. Esto hace que la estructura del código de generación XML se parezca mucho al XML en sí.

Una ventaja de esto es que puede generar grandes cantidades de XML de manera eficiente si se transmite a un archivo. Pagará los costos de validación más tarde (presumiblemente en un mejor momento para una operación costosa).

La desventaja de esta técnica es que es esencialmente solo de salida. No es adecuado para crear y luego consumir XML dinámicamente.

+0

muchas gracias! Pasé las últimas 2 o 3 horas explorando la web, grupos de noticias, irc, etc. y en los últimos 20 minutos construí un generador que hace exactamente lo que necesito hacer con este método: no es hermoso; necesita trabajo, pero FUNCIONA, ¡gracias! – eyberg

+3

¡Sí, Hereje! ;) En serio, recomendaría no seguir esta ruta: hay muchas bibliotecas que ayudarán y evitarán que cometas errores en tu XML. – MattyT

+0

Bueno, he estado generando mi propio XML por años sin problemas. Al igual que Foredecker, nuestro XML es relativamente simple pero, quizás, más complicado de lo que él dice. – Rob

0

¿Qué plataforma? MSXML es una opción en Windows. CMarkup es otra buena opción. Si .NET es una opción, tiene una excelente compatibilidad con XML.

+0

CMarkup también funciona sin .Net Puede compilarlo para usar std :: string o MFC CString. Construye todo el documento en la memoria si es un problema –

0

No he intentado aumentar la serialización para hacer esto, pero según tengo entendido, si selecciona cuidadosamente sus opciones, puede establecer muchas opciones diferentes en el esquema (como evitar el sobrepeso del puntero y establecer el elemento nombres para ciertos tipos)

47

Recientemente revisé un grupo de bibliotecas XML específicamente para generar código XML.

Resumen ejecutivo: elegí ir con TinyXML++.

TinyXML ++ tiene una sintaxis decente C++, está construido en las librerías maduras TinyXML C, es libre & de código abierto (licencia MIT) y pequeño. En resumen, ayuda a hacer el trabajo rápidamente. He aquí un fragmento rápida:

Document doc; 
Node* root(doc.InsertEndChild(Element("RootNode"))); 
Element measurements("measurements"); 
Element tbr("TotalBytesReceived", 12); 
measurements.InsertEndChild(tbr); 
root->InsertEndChild(measurements); 

que produce:

<RootNode> 
    <measurements> 
     <TotalBytesReceived>12</TotalBytesReceived> 
    </measurements> 
</RootNode> 

He sido muy feliz con ella.

He revisado muchos otros; aquí están algunos de los mejores contendientes:

Xerces: The king-daddy. ¿Tiene todo (especialmente cuando se combina con Xalan) pero es pesado y fuerza la administración de la memoria en el usuario.

RapidXML: Excelente para el análisis (que es un programa de análisis in-situ y es rápido ) pero no es bueno para la generación desde la adición de nodos para el DOM requiere la gestión de memoria.

Boost.XML (propuesta): Aspecto excelente - poderosa, excelente sintaxis de C++. Sin embargo, aún no ha pasado por el proceso de revisión, no es compatible y la interfaz puede cambiar. Casi lo usé de todos modos. Esperando su aceptación en Boost.

Libxml (++): Muy bueno; sintaxis decente y decente Pero es muy grande si todo lo que hace es generando XML y está vinculado a la biblioteca glibmm (para ustring). Si fuéramos solo en Linux (¿como usted?) Lo consideraría seriamente.

XiMOL: Biblioteca única basada en secuencias. Esto fue un poco demasiado simplista para nuestras necesidades, pero para la generación básica de XML, puede que le resulte bastante útil. La sintaxis de la secuencia es bastante clara.

¡Espero que haya algo allí de alguna utilidad!

+0

Al mirar la página TinyXML ++ issues, parece que tiene algunas pérdidas de memoria. ¿Has experimentado eso? – metal

+0

@mlimber Lo uso bastante regularmente y no lo he hecho, pero solo lo uso para documentos relativamente pequeños –

+5

Hm, mirando el elemento más interno dudo que la salida y el código coincidan. :-) –

0

uso tinyXml ++ y hace que sea muy fácil crear xml como se publicó anteriormente. También lo guardará en un archivo en un comando pero no puedo encontrar la manera de guardarlo en un buffer.

9

Boost.PropertyTree es una forma sencilla y directa de generar XML, especialmente si ya está utilizando Boost.

El siguiente es un ejemplo de programa completo:

#include <boost/property_tree/ptree.hpp> 
#include <boost/property_tree/xml_parser.hpp> 

using boost::property_tree::ptree; 
using boost::property_tree::write_xml; 
using boost::property_tree::xml_writer_settings; 

int wmain(int argc, wchar_t* argv[]) { 
    char* titles[] = {"And Then There Were None", "Android Games", "The Lord of the Rings"}; 

    ptree tree; 
    tree.add("library.<xmlattr>.version", "1.0"); 
    for (int i = 0; i < 3; i++) { 
     ptree& book = tree.add("library.books.book", ""); 
     book.add("title", titles[i]); 
     book.add("<xmlattr>.id", i); 
     book.add("pageCount", (i+1) * 234); 
    } 

    // Note that starting with Boost 1.56, the template argument must be std::string 
    // instead of char 
    write_xml("C:\\Users\\Daniel\\Desktop\\test.xml", tree, 
     std::locale(), 
     xml_writer_settings<char>(' ', 4)); 

    return 0; 
} 

El XML resultante es la siguiente:

<?xml version="1.0" encoding="utf-8"?> 
<library version="1.0"> 
    <books> 
     <book id="0"> 
      <title>And Then There Were None</title> 
      <pageCount>234</pageCount> 
     </book> 
     <book id="1"> 
      <title>Android Games</title> 
      <pageCount>468</pageCount> 
     </book> 
     <book id="2"> 
      <title>The Lord of the Rings</title> 
      <pageCount>702</pageCount> 
     </book> 
    </books> 
</library> 

Una cosa que es particularmente agradable son los caminos separados por puntos que le permiten crear de forma implícita todos los nodos en el camino. El documentation es bastante pobre, pero junto con ptree.hpp debería darle una idea de cómo funciona.

Cuestiones relacionadas