2010-05-11 19 views
16

Devo analizzare un file XML in C++. Stavo facendo ricerche e ho trovato la libreria RapidXml per questo.Come analizzare il file XML in RapidXML

Ho dubbi su doc.parse<0>(xml).

Can xml può essere .xml o deve essere un string o char *?

Se può richiedere solo string o char *, allora suppongo di aver bisogno di leggere l'intero file e di memorizzarlo in un array di caratteri e passare il puntatore di esso alla funzione?

C'è un modo per utilizzare direttamente il file perché avrei bisogno di cambiare anche il file XML all'interno del codice.

Se non è possibile in RapidXML, suggerire altre librerie XML in C++.

Grazie !!!

Ashd

+1

L'argomento di xml_document :: parse() è una stringa a terminazione zero contenente xml. Quindi hai solo bisogno di creare una funzione file2string. Leggere il file in un vettore buffer e quindi passare & buffer [0] a parse(). – anno

+0

vtd-xml ha anche una porta C++, rispetto a rapidXML, vtd-xml è molto più conforme, stabile ed efficiente ... –

risposta

0

Il manual ci dice:

funzione xml_document :: parse

[...] analizza terminata da zero stringa XML secondo determinate bandiere.

RapidXML lascia caricare i dati carattere da un file. O leggere il file in un buffer, come suggerito da anno o in alternativa utilizzare una tecnica di mappatura della memoria. (Ma guarda prima la bandiera parse_non_destructive.)

7

Nuovo al C++ ... ma volevo condividere una soluzione.

YMMV!

Shout Out per SiCrane su questo thread: - e solo sostituendo 'stringa' con un vettore --- (anno grazie)

Si prega di commentare e mi aiuta a imparare anche! Sono molto nuovo a questo

In ogni caso, questo sembra funzionare per un buon inizio:

#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

Funziona bene, ma solo se 'vector buffer' non rientra nell'ambito: a modo rapido e sporco per risolvere questo problema aggiungendo la parola chiave 'statica' al vettore, ma non penso che sia veramente pulito. Vedere questo: http://stackoverflow.com/questions/6363719/rapidxml-reading-from-file-what-is-wrong-here – FlipMcF

2

Noi di solito leggere il codice XML dal disco in un std::string, poi fare una copia di sicurezza in un std::vector<char> come illustrato di seguito:

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]); 

Per un controllo completo codice sorgente:

Read a line from xml file using C++

+0

Questo è troppo lento a causa del ridimensionamento del vettore. Confronta con la risposta di Superfly Jon, è molto più veloce. –

26

RapidXml viene fornito con una classe per fare questo per voi, rapidxml::file nel file rapidxml_utils.hpp. Qualcosa di simile:

#include "rapidxml_utils.hpp" 

int main() { 
    rapidxml::file<> xmlFile("somefile.xml"); // Default template is char 
    rapidxml::xml_document<> doc; 
    doc.parse<0>(xmlFile.data()); 
... 
} 

Nota che l'oggetto xmlFile ora contiene tutti i dati per l'XML, il che significa che una volta che va fuori del campo di applicazione e viene distrutto la variabile doc non è più in modo sicuro utilizzabile. Se si chiama parse all'interno di una funzione, è necessario in qualche modo conservare l'oggetto xmlFile in memoria (variabile globale, nuova, ecc.) In modo che il documento rimanga valido.