Я пытаюсь использовать для анализа моего XML-файла. И я сделал это после example here. Вместо того, чтобы выполнять синтаксический анализ в основной функции, я написал класс оболочки, называемый XMLParser, для выполнения задания синтаксического анализа. И это действительно дает мне головную боль.C++ Использование RapidXml для разбора XML-файла, класса Wrapper, parse_error ожидать>
XMLParser.hpp:
#include <iostream>
#include <string>
#include <stdio.h>
#include <vector>
#include "rapidxml/rapidxml.hpp"
using namespace std;
using namespace rapidxml;
class XMLParser {
public:
XMLParser() {};
XMLParser(const std::string &xmlString): xmlCharVector(xmlString.begin(), xmlString.end())
{
//xmlCharVector.push_back('\0');
parseXML();
}
XMLParser(const std::vector<char> &_xmlVector):xmlCharVector(_xmlVector)
{
/* xmlCharVector.push_back('\0'); */ // already done in main.cpp
if (xmlCharVector != _xmlVector) //And it turns out they're the same....
std::cout << "The two vectors are not equal" << std::endl;
else
std::cout << "They are the same" << std::endl;
parseXML();
}
private:
std::vector<char> xmlCharVector;
rapidxml::xml_document<> doc;
void parseXML();
};
XMLParser.cpp:
#include "XMLParser.hpp"
using namespace std;
using namespace rapidxml;
void XMLParser::parseXML()
{
doc.parse<0>(&xmlCharVector[0]);
}
А вот main.cpp:
#include <iostream>
#include <stdio.h>
#include <string>
#include <vector>
#include <fstream>
#include "XMLParser.hpp"
using namespace std;
using namespace rapidxml;
int main(int argc, char **argv)
{
xml_document<> doc;
xml_node<> *root_node;
ifstream theFile("beer.xml");
vector<char> buffer((istreambuf_iterator<char>(theFile)), istreambuf_iterator<char>());
buffer.push_back('\0');
doc.parse<0>(&buffer[0]);
root_node = doc.first_node("MyBeerJournal");
xml_node<> *engine = root_node->first_node("Brewery");
//The above code works pretty well, and I can get the element I want in XML file.
//The problem occurs when I tried to use the XMLParser
XMLParser xmlParser(buffer);
return 0;
}
Процесс синтаксического анализа в основной функции работает очень хорошо. Но когда я пытался использовать функцию в моей обертку класса parseXML()
, то произошла ошибка:
Terminate вызывается после метания экземпляр «rapidxml :: parse_error» , что(): ожидаемый> Abort (ядро сбрасывали)
Первоначально у меня есть другой код в этой функции, но я прокомментировал их все и обнаружил, что даже с одной строкой doc.parse<0>(&xmlCharVector[0]);
. Почему он хорошо работает в main.cpp, а не в классе-оболочке? Я действительно не могу понять это. Может ли кто-нибудь помочь мне?
* «Я не знаю, почему библиотечный писатель должен изменить вектор символов, переданный в * *. Поскольку RapidXML разработан как сверхбыстрый * in-situ * парсер. Созданный DOM представляет собой просто набор указателей в исходные данные. Прочтите документы, * конкретно * раздел о «отличиях от обычных парсеров XML». http://rapidxml.sourceforge.net/manual.html – Roddy
@Roddy Это означает, что функция будет редактировать исходную строку напрямую с помощью указателя, а не сначала скопировать его, а затем сделать что-то на скопированном? – Dreamer
Точно: он помещает нулевые символы для завершения каждого «узла», если вы не используете «неразрушающий» режим. Это позволяет избежать накладных расходов на скорость распределения памяти для хранения каждого узла и накладных расходов на память, требующих второй немодифицированной копии. – Roddy