Как проанализировать файл XML с RapidXml - PullRequest
18 голосов
/ 11 мая 2010

Я должен проанализировать XML-файл в C ++. Я искал и нашел для этого библиотеку RapidXml.

У меня есть сомнения по поводу doc.parse<0>(xml).

Может ли xml быть XML-файлом или это должен быть string или char *?

Если я могу использовать только string или char *, тогда, я думаю, мне нужно прочитать весь файл и сохранить его в массиве символов и передать указатель на функцию?

Есть ли способ напрямую использовать файл, потому что мне нужно было бы также изменить файл XML внутри кода.

Если это невозможно в RapidXml, пожалуйста, предложите некоторые другие библиотеки XML в C ++.

Спасибо !!!

Ashd

Ответы [ 4 ]

29 голосов
/ 25 января 2013

RapidXml поставляется с классом, чтобы сделать это для вас, rapidxml::file в файле rapidxml_utils.hpp. Что-то вроде:

#include "rapidxml_utils.hpp"

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

Обратите внимание, что объект xmlFile теперь содержит все данные для XML, что означает, что после того, как он выходит из области видимости и уничтожается, переменная doc больше не может безопасно использоваться. Если вы вызываете parse внутри функции, вы должны каким-то образом сохранить объект xmlFile в памяти (глобальная переменная, new и т. Д.), Чтобы документ оставался действительным.

8 голосов
/ 15 мая 2011

Я новичок в C ++ ... но я хотел поделиться решением.

YMMV!

Обращайтесь к SiCrane по этой теме : - и просто заменив 'строку' на вектор --- (спасибо anno)

Пожалуйста, прокомментируйте и помогите мне учиться! Я очень новичок в этом

В любом случае, это похоже на хорошее начало:

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


}
1 голос
/ 14 июня 2011

Обычно мы читаем XML с диска в std::string, а затем делаем его безопасную копию в std::vector<char>, как показано ниже:

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

Для полной проверки исходного кода:

Считать строку из XML-файла, используя C ++

0 голосов
/ 13 сентября 2010

руководство говорит нам:

функция xml_document :: parse

[...] Анализирует строку XML с нулем в конце в соответствии с заданными флагами.

RapidXML оставляет загрузку символьных данных из файла вам. Либо прочитайте файл в буфер, как предложено anno , либо используйте метод отображения памяти (Но сначала посмотрите parse_non_destructive флаг.)

...