2010-05-11 21 views
16

Tengo que analizar un archivo XML en C++. Estaba investigando y encontré la biblioteca RapidXml para esto.Cómo analizar el archivo XML en RapidXML

Tengo dudas sobre doc.parse<0>(xml).

¿Puede xml ser un archivo .xml o tiene que ser un string o char *?

Si solo puede tomar string o char *, entonces supongo que necesito leer el archivo completo y almacenarlo en una matriz char y pasar el puntero de la misma a la función?

¿Hay alguna manera de utilizar directamente el archivo porque también necesitaría cambiar el archivo XML dentro del código?

Si no es posible en RapidXML, sugiera algunas otras bibliotecas XML en C++.

Gracias !!!

Ashd

+1

El argumento de xml_document :: parse() es una cadena terminada en cero que contiene el xml. Entonces solo necesitas crear una función file2string. Lea el archivo en un buffer vector y luego pase & buffer [0] para analizar(). – anno

+0

vtd-xml también tiene un puerto C++, en comparación con rapidXML, vtd-xml es mucho más conforme, estable y eficiente ... –

Respuesta

0

El manual nos dice:

función xml_document :: analizar

[...] un análisis sintáctico XML cadena terminada en cero acuerdo con banderas dadas.

RapidXML deja de cargar los datos del caracter de un archivo. Lea el archivo en un búfer, como anno, o alternativamente, utilice alguna técnica de asignación de memoria. (Pero busque primero la bandera parse_non_destructive)

7

Nuevo en C++ yo mismo ... pero quería compartir una solución.

YMMV!

grito a SiCrane en este thread: - y sólo la sustitución de 'cadena' con un vector --- (anno gracias)

Por favor, comentar y me ayudan a aprender también! Soy muy nuevo en este

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 */ 


} 
+0

Esto funciona bien, pero solo si 'vector buffer' no cae fuera del alcance: a Una manera rápida y sucia de resolver esto es agregar la palabra clave "estática" al vector, pero no creo que eso esté realmente limpio. Consulte esto: http://stackoverflow.com/questions/6363719/rapidxml-reading-from-file-what-is-wrong -here – FlipMcF

2

generalmente Leemos el XML desde el disco en un std::string, a continuación, hacer una copia de seguridad de la misma en una std::vector<char> como se demuestra 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 revisión completa de código fuente:

Read a line from xml file using C++

+0

Esto es demasiado lento debido al cambio de tamaño del vector. Compare con la respuesta de Superfly Jon, es mucho más rápido. –

26

RapidXml viene con una clase para hacer esto por usted, rapidxml::file en el archivo rapidxml_utils.hpp. Algo así 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 del XML, lo que significa que una vez que se sale del ámbito y se destruye la variable doc ya no es segura utilizable. Si llama al análisis dentro de una función, debe conservar el objeto xmlFile de alguna manera en la memoria (variable global, nuevo, etc.) para que el documento permanezca válido.

Cuestiones relacionadas