C++ (C+;+;)解析伪XML
C++ (C+;+;)解析伪XML,c++,xml,parsing,C++,Xml,Parsing,我正在尝试了解更多关于C++的内容,我正在制作一个(相当简单的)2D地图编辑器。我目前有一个工作非常好的系统,但我正试图通过使用标签来改进 我想要完成的 我希望能够加载一个文本文件,并让它在一个级别中存储我可能需要的所有数据(包括但不限于:瓷砖、背景、对象、播放器等)。这些文本文件将由我的地图编辑器生成,因此我可以完全控制它们的创建方式和结构。虽然这不是一个学校项目,我正在尝试更多地了解C++,所以我宁愿尽可能少地使用依赖关系(我目前只使用SFML,但我认为这不是相关的),因此我为什么不使用现
我正在尝试了解更多关于C++的内容,我正在制作一个(相当简单的)2D地图编辑器。我目前有一个工作非常好的系统,但我正试图通过使用标签来改进 我想要完成的
我希望能够加载一个文本文件,并让它在一个级别中存储我可能需要的所有数据(包括但不限于:瓷砖、背景、对象、播放器等)。这些文本文件将由我的地图编辑器生成,因此我可以完全控制它们的创建方式和结构。虽然这不是一个学校项目,我正在尝试更多地了解C++,所以我宁愿尽可能少地使用依赖关系(我目前只使用SFML,但我认为这不是相关的),因此我为什么不使用现有的XML解析器。
//Call to my parser
getTagContents("Resources/xmltester.txt", "mytag");
//
void getTagContents(std::string文件到分段位置,std::string标记名)
{
int lineNumberToFindTagName=0;
int lineNumberToFindTagNameEnd=0;
std::向量标记线;
std::向量标记;
std::载体标记内容;
字符串模板;
std::fstream filetoparsed(filetoparsedLocation);
if(fileToBeParsed.is_open())
{
而(!fileToBeParsed.eof())
{
while(std::getline(fileToBeParsed,line))
{
//开场白
if(line.find(“”==-1)
{
lineNumberToFindTagName++;
}
其他的
{
std::size\u t pos=line.find(“”);
std::cout不要这样做。您试图在不了解解析技术的情况下实现XML解析器。此项目永远不会以完全失败而告终
您需要的是一个现有的XML解析器,它有两种变体,SAX风格的解析按顺序读取文件,DOM风格的解析将文件读入一个全面的数据结构
最流行的C(和C++)SAX风格解析库是ExpT。我不确定它是否有面向对象的C++包装器,但如果不是,如果你真的知道C++,那么你可以在比自己的XML解析器更少的时间内实现它。
如果需要DOM样式解析,一个选项是处理SAX风格分析器中的事件并构造解析树。另一个选项是查看是否有DOM样式的C/C++解析库。C++的库可能是更好的选择,DOM样式库本质上是面向对象的,并且您希望使用完整的特性。对于C++语言来说,
要了解有关解析XML的各种方法的更多信息,请参阅
XML的简单API意味着SAX,文档对象模型意味着DOM
如果您确实想实现自己的XML解析器,最好学习现有技术(即基于SAX的解析和基于DOM的解析)首先,决定要使用哪一种。原型解析器既不代表这两种类型,而且franky看起来根本不是解析XML的成功方法。结束标记呢?知道开头的“>”和可以使用的“”字符的位置seekg()我不确定XML是这里最好的选择。直到你更熟悉C++的基本语法分析功能,最好是创建一个更简单的格式。这非常类似于数据如何存储在游戏本身。Amadeusz,我想到了这样的方法,但是我担心我不会。能够读取多行。我试图存储的数据之一是我的地图本身,虽然在阅读文件后我知道它有多大,但它可能是巨大的(不确定硬件限制可能是什么,但我希望它甚至可能是每边数十万).如果这根本不可能,我可以试着找到另一种方法。你能详细说明一下为什么你认为这不是一种好的方法(只是在这里尝试学习)?我想如果我能从某个位置(我已经知道)找出如何阅读的方法,我可以在读取数据时计算出如何处理数据。由于我要读取文件,我可以轻松地控制格式。谢谢。这类似于用正则表达式解析HTML/XML的流行问题。是的,你可以这样做,但决不能以一种对所有可能的HTML/XML文件都安全的方式。我想如果你控制格式方法可能是一段时间,但当需要扩展格式,你发现自己很快再次陷入。考虑的可能性,有人编辑文件的文本编辑器的方式,使他们不可读你的黑客解析器,但可读的一个适当的XML解析器。如果你真的想使用的方法,你使用,那么也许其他人可以帮助我。虽然我想为任何事件做好准备,但如果有人篡改了文件,那是他们的错,为了让我了解这是如何工作的,我会选择忽略这一点。如果你仍然认为我不应该费事让我知道,你可能会说服我:P(出于好奇,如果我试图读取标记之间的所有内容,那么处理文件的人产生XML可以读取的内容的可能性有多大,而我却不能?)
//
void getTagContents(std::string fileToBeParsedLocation, std::string tagName)
{
int lineNumberToFindTagName = 0;
int lineNumberToFindTagNameEnd = 0;
std::vector<int> tagsLine;
std::vector<int> tagsPos;
std::vector<std::string> tagContents;
std::string tempLine;
std::fstream fileToBeParsed(fileToBeParsedLocation);
if (fileToBeParsed.is_open())
{
while (!fileToBeParsed.eof())
{
while (std::getline(fileToBeParsed, line))
{
//Opening tag
if (line.find("<" + tagName + ">") == -1)
{
lineNumberToFindTagName++;
}
else
{
std::size_t pos = line.find("<" + tagName + ">");
std::cout << "Found tag " << tagName << " opening at line " << lineNumberToFindTagName << " at position " << pos << std::endl;
tagsLine.push_back(lineNumberToFindTagName);
tagsPos.push_back(pos);
lineNumberToFindTagName++;
//Test
//std::getline(fileToBeParsed, tempLine);
//std::cout << tempLine;
//This returns really strange values
}
//Closing tag
if (line.find("</" + tagName + ">") == -1)
{
lineNumberToFindTagNameEnd++;
}
else
{
std::size_t pos = line.find("</" + tagName + ">");
std::cout << "Found tag " << tagName << " closing at line " << lineNumberToFindTagNameEnd << " at position " << pos << std::endl;
tagsLine.push_back(lineNumberToFindTagNameEnd);
tagsPos.push_back(pos);
lineNumberToFindTagNameEnd++;
}
}
}
//Size of tagContents will always be half of either tagsLine or tagsPos (it doesn't matter which)
for (int i = 0; i < tagsPos.size()/2; i++)
{
for (int j = 0; j < tagsLine[i]; j++)
{
//I think this is where most of the stuff I need to add should go
}
std::getline(fileToBeParsed, tempLine);
std::stringstream stream(tempLine);
std::cout << "Line contents: " << tempLine << "<>" << std::endl;
}
}
for (int i = 0; i < tagsPos.size(); i++)
{
std::cout << tagsLine[i] << "." << tagsPos[i] << std::endl;
}
getchar();
getchar();
}