c++ - Cómo analizar un archivo XML con RapidXml
parsing (4)
El manual nos dice:
funcion xml_document :: parse
[...] Analiza la cadena XML terminada en cero de acuerdo con las banderas dadas.
RapidXML te deja cargar los datos de caracteres de un archivo. Puede leer el archivo en un búfer, como no se sugiere, o usar una técnica de mapeo de memoria. (Pero primero busque la parse_non_destructive
).
Tengo que analizar un archivo XML en C ++. Estaba investigando y encontré la biblioteca RapidXml para esto.
Tengo dudas sobre doc.parse<0>(xml)
.
¿Puede xml
ser un archivo .xml o debe ser una string
o un char *
?
Si solo puedo usar string
o char *
entonces creo que necesito leer todo el archivo y almacenarlo en una matriz de caracteres y pasar el puntero a la función.
¿Hay una manera de usar directamente un archivo porque también necesitaría cambiar el archivo XML dentro del código?
Si eso no es posible en RapidXml, sugiera algunas otras bibliotecas XML en C ++.
¡¡¡Gracias!!!
Ashd
Por lo general, leemos el XML del disco en una std::string
, luego hacemos una copia segura de él en un std::vector<char>
como se muestra a continuación:
string input_xml;
string line;
ifstream in("demo.xml");
// read file into input_xml
while(getline(in,line))
input_xml += line;
// make a safe-to-modify copy of input_xml
// (you should never modify the contents of an std::string directly)
vector<char> xml_copy(input_xml.begin(), input_xml.end());
xml_copy.push_back(''/0'');
// only use xml_copy from here on!
xml_document<> doc;
// we are choosing to parse the XML declaration
// parse_no_data_nodes prevents RapidXML from using the somewhat surprising
// behavior of having both values and data nodes, and having data nodes take
// precedence over values when printing
// >>> note that this will skip parsing of CDATA nodes <<<
doc.parse<parse_declaration_node | parse_no_data_nodes>(&xml_copy[0]);
Para una verificación completa del código fuente:
RapidXml viene con una clase para hacer esto por ti, rapidxml::file
en el archivo rapidxml_utils.hpp
. Algo como:
#include "rapidxml_utils.hpp"
int main() {
rapidxml::file<> xmlFile("somefile.xml"); // Default template is char
rapidxml::xml_document<> doc;
doc.parse<0>(xmlFile.data());
...
}
Tenga en cuenta que el objeto xmlFile
ahora contiene todos los datos para el XML, lo que significa que una vez que está fuera del alcance y se destruye, la variable doc ya no se puede usar de manera segura. Si llama a analizar dentro de una función, debe conservar de alguna manera el objeto xmlFile
en la memoria (variable global, nuevo, etc.) para que el documento siga siendo válido.
Yo mismo soy nuevo en C ++ ... pero quería compartir una solución.
YMMV!
Grita a SiCrane en este thread : - y simplemente reemplaza ''cadena'' con un vector --- (gracias, anno)
Por favor comenta y ayúdame a aprender también! Soy muy nuevo en esto
De todos modos, esto parece funcionar para un buen comienzo:
#include <iostream>
#include <fstream>
#include <vector>
#include "../../rapidxml/rapidxml.hpp"
using namespace std;
int main(){
ifstream myfile("sampleconfig.xml");
rapidxml::xml_document<> doc;
/* "Read file into vector<char>" See linked thread above*/
vector<char> buffer((istreambuf_iterator<char>(myfile)), istreambuf_iterator<char>( ));
buffer.push_back(''/0'');
cout<<&buffer[0]<<endl; /*test the buffer */
doc.parse<0>(&buffer[0]);
cout << "Name of my first node is: " << doc.first_node()->name() << "/n"; /*test the xml_document */
}