2008-09-01 16 views
12

En mi programa C++ quiero analizar una pequeña porción de XML, insertar algunos nodos y luego extraer el nuevo XML (preferiblemente como std::string).
RapidXml me ha sido recomendado, pero no puedo ver cómo recuperar el XML como una cadena de texto.
(Pude iterar sobre los nodos y atributos y construirlo yo mismo, pero seguramente hay una versión en la función que me falta).
Gracias.C++: Cómo extraer una cadena de RapidXml

Respuesta

9

Aunque la documentación es pobre en este tema, logré obtener algún código de funcionamiento mirando la fuente. Aunque le falta el encabezado xml que normalmente contiene información importante. He aquí un pequeño ejemplo de programa que hace lo que está buscando usando rapidxml:

#include <iostream> 
#include <sstream> 
#include "rapidxml/rapidxml.hpp" 
#include "rapidxml/rapidxml_print.hpp" 

int main(int argc, char* argv[]) { 
    char xml[] = "<?xml version=\"1.0\" encoding=\"latin-1\"?>" 
       "<book>" 
       "</book>"; 

    //Parse the original document 
    rapidxml::xml_document<> doc; 
    doc.parse<0>(xml); 
    std::cout << "Name of my first node is: " << doc.first_node()->name() << "\n"; 

    //Insert something 
    rapidxml::xml_node<> *node = doc.allocate_node(rapidxml::node_element, "author", "John Doe"); 
    doc.first_node()->append_node(node); 

    std::stringstream ss; 
    ss <<*doc.first_node(); 
    std::string result_xml = ss.str(); 
    std::cout <<result_xml<<std::endl; 
    return 0; 
} 
0

Si todavía no está comprometido con XML rápido, puedo recomendar algunas bibliotecas alternativas:

+0

Simplemente no olvide las pocas penalidades de velocidad del cien por ciento para estas bibliotecas, aunque ambas tienen muchas más características que RapidXML. –

+0

vtd-xml es una lib más que es más conforme y potente que rapidXML –

2

Si construye XML a sí mismo, no se olvide de escapar los caracteres especiales. Esto tiende a ser pasado por alto, pero puede causar algunos dolores de cabeza graves si no se implementa:

  • <               & lt;
  • >               & gt;
  • &               & amp;
  • "               & quot;
  • '               & apos;
6

Uso print función (que se encuentra en rapidxml_print.hpp colector de servicio) para imprimir el contenido del nodo XML en un stringstream.

+0

Excelente, que me permite suprimir la indentación de nodo – hamishmcn

+0

¿Puede dar un ejemplo? – Qsiris

2

continuación se explica cómo imprimir un nodo en una cadena recta desde el RapidXML Manual:

xml_document<> doc; // character type defaults to char 
// ... some code to fill the document 

// Print to stream using operator << 
std::cout << doc; 

// Print to stream using print function, specifying printing flags 
print(std::cout, doc, 0); // 0 means default printing flags 

// Print to string using output iterator 
std::string s; 
print(std::back_inserter(s), doc, 0); 

// Print to memory buffer using output iterator 
char buffer[4096];      // You are responsible for making the buffer large enough! 
char *end = print(buffer, doc, 0);  // end contains pointer to character after last printed character 
*end = 0;        // Add string terminator after XML 
2

rapidxml :: impresión reuqires un iterador de salida para generar la salida, por lo que una cadena de caracteres trabaja con él.Pero esto es arriesgado porque no puedo saber si una matriz con longitud fija (como 2048 bytes) es lo suficientemente larga como para contener todo el contenido del XML.

La forma correcta de hacer esto es pasar un iterador de salida de una secuencia de cadena para permitir que el búfer se expanda cuando el XML se está volcando en él.

Mi código es como a continuación:

std::stringstream stream; 
std::ostream_iterator<char> iter(stream); 

rapidxml::print(iter, doc, rapidxml::print_no_indenting); 

printf("%s\n", stream.str().c_str()); 
printf("len = %d\n", stream.str().size()); 
0

Uso static_cast <>

Ex:

rapidxml::xml_document<> doc; 
rapidxml::xml_node <> * root_node = doc.first_node(); 
std::string strBuff; 

doc.parse<0>(xml); 

. 
. 
. 
strBuff = static_cast<std::string>(root_node->first_attribute("attribute_name")->value()); 
0

que sigue es muy fácil,

std::string s; 
print(back_inserter(s), doc, 0); 
cout << s; 

Sólo es necesario incluye "rapidxml" _print.hpp "encabezado en su código fuente.

Cuestiones relacionadas