(C ++)解析伪XML

时间:2015-03-19 20:35:41

标签: c++ xml parsing


我试图了解更多关于C ++的知识,并且我正在制作(非常简单的)2D地图编辑器。我目前有一个运行良好的系统,但我试图通过使用标签来改进。

我想要完成的事情
我希望能够加载一个文本文件,并将它存储在一个级别中可能需要的所有数据(包括但不限于:磁贴,背景,对象,播放器等)。这些文本文件将由我的地图编辑器生成,因此我可以完全控制它们的创建方式和结构。 虽然这不是一个学校项目,但我试图了解更多关于C ++的知识,所以我宁愿使用尽可能少的依赖项(我目前只使用SFML,但是我不认为这与此相关),因此我没有使用现有的XML Parser。



//Call to my parser
getTagContents("Resources/xmltester.txt", "mytag");


//
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();
}


问题是什么
这可能主要是由于我的无能,但我不知道如何使用我知道标签的事实。行和位置值,以便在它们之间进行读取。它应该是微不足道的,但我无法找到一种方法来确保我能正确读取任何数量的标签...


有什么想法吗? (并提前感谢)

1 个答案:

答案 0 :(得分:0)

不要那样做。您正在尝试在不知道解析技术的情况下实现XML解析器。除了完全失败之外,这个项目永远不会结束。

你需要的是一个现有的XML解析器,它有两种变体,SAX样式解析按顺序读取文件,DOM样式解析将文件读入综合数据结构。

C(和C ++)最流行的SAX样式解析库是expat。我不确定它是否有面向对象的C ++包装器,但如果没有,如果你真的了解C ++,你可以用更少的时间来实现它,而不是自己的XML解析器。

如果需要DOM样式的解析,一个选项是处理SAX样式解析器中的事件并构造一个解析树。另一个选择是查看是否有任何DOM风格的C / C ++解析库。可能C ++库是一个更好的选择,因为DOM风格的库本质上是面向对象的,你确实想要为它们使用C ++语言的全部功能。

要了解有关解析XML的各种方法的更多信息,请参阅http://en.wikipedia.org/wiki/XML#Programming_interfaces

Simple API for XML意味着SAX和文档对象模型意味着DOM。

如果你真的想要实现自己的XML解析器,最好先研究现有技术(即基于SAX的解析和基于DOM的解析),然后决定你想要哪些解析器。你的原型解析器既不代表,也不是franky看起来不像是解析XML的成功方法。