c++ xml rapidxml

C++: cómo extraer una cadena de RapidXml



(8)

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

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

En mi programa C ++ quiero analizar un pequeño fragmento de XML, insertar algunos nodos y luego extraer el nuevo XML (preferentemente como std::string ).
Se me recomendó RapidXml , pero no veo cómo recuperar el XML como una cadena de texto.
(Podría iterar sobre los nodos y atributos y construirlo yo mismo, pero seguramente hay una función de compilación que me falta).
Gracias.


Aunque la documentación es pobre sobre este tema, logré obtener un código de trabajo mirando la fuente. Aunque le falta el encabezado xml que normalmente contiene información importante. Aquí hay un pequeño programa de ejemplo 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; }


Lo siguiente es muy fácil,

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

Solo necesita incluir el encabezado "rapidxml_print.hpp" en su código fuente.


Si aún no está comprometido con Rapid XML, puedo recomendar algunas bibliotecas alternativas:


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

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

Usar 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());


Utilice print función de print (que se encuentra en el encabezado de la rapidxml_print.hpp ) para imprimir los contenidos del nodo XML en una stringstream .


rapidxml :: print requiere un iterador de salida para generar el resultado, por lo que una cadena de caracteres funciona 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 hacerlo es pasar un iterador de salida de una secuencia de cadenas para permitir que el buffer 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());