Как проанализировать файл XML с RapidXml
Я должен проанализировать файл XML в C++. Я искал и нашел для этого библиотеку RapidXml.
У меня есть сомнения по поводу doc.parse<0>(xml)
.
Может ли xml
быть XML файлом или это должна быть string
или char *
?
Если я могу использовать только string
или char *
тогда я предполагаю, что мне нужно прочитать весь файл и сохранить его в массиве символов и передать указатель на функцию?
Есть ли способ напрямую использовать файл, потому что мне нужно будет также изменить файл XML внутри кода.
Если это невозможно в RapidXml, предложите другие библиотеки XML в C++.
Спасибо!!!
Ashd
Ответы
Ответ 1
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 более безопасна для использования. Если вы вызываете синтаксический анализ внутри функции, вы должны каким-то образом сохранить объект xmlFile
в памяти (глобальная переменная, новый и т.д.), Чтобы документ оставался действительным.
Ответ 2
Новый для С++ сам... но я хотел поделиться решением.
YMMV!
Перейдите в SiCrane на этот поток:
- и просто заменив "string" на вектор --- (спасибо 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 */
}
Ответ 3
Обычно мы читаем 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 файла с помощью С++
Ответ 4
manual сообщает нам:
функция xml_document:: parse
[...] Парсирует XML-строку с нулевым завершением согласно заданным флагам.
RapidXML оставляет загружаемые вами персональные данные из файла. Либо прочитайте файл в буфер, например anno, либо используйте альтернативную технологию отображения памяти. (Но сначала найдите флаг parse_non_destructive
.)