【问题标题】:(C++)Parsing Pseudo-XML(C++)解析伪 XML
【发布时间】:2015-05-23 03:39:18
【问题描述】:


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

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



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


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


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

【问题讨论】:

  • 结束标签呢?知道开始标签的“>”和结束标签的“fstream 的get() 函数读取它们之间的内容。要在 '>' 字符上设置光标位置,您可以使用 seekg() 函数。
  • 就我个人而言,我不确定 XML 是这里的最佳选择。在您更熟悉 C++ 中的基本解析函数如何工作之前,创建一个更简单的格式可能会更好。与游戏本身的数据存储方式非常相似。
  • Amadeusz,我想过这样的方法,但我担心我不能阅读超过一行。我要存储的数据之一是我的地图本身,虽然我会在阅读文件后知道它有多大,但它可能会很大(不确定硬件限制可能是什么,但我我希望它甚至可能每边都有几十万)。如果这根本不可能,我可以尝试另一种方法。

标签: c++ xml parsing


【解决方案1】:

不要那样做。您试图在不了解解析技术的情况下实现 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

XML 的简单 API 表示 SAX,文档对象模型表示 DOM。

如果您确实想实现自己的 XML 解析器,最好先研究现有技术(即基于 SAX 的解析和基于 DOM 的解析)并决定您想要其中的哪一个。您的原型解析器两者都不代表,而且 franky 看起来根本不是解析 XML 的成功方法。

【讨论】:

  • 您能否详细说明为什么您认为这不是一个好方法(只是想在这里学习)?我想如果我能弄清楚如何从某个位置(我已经知道)读取数据,我就可以在读取数据时弄清楚如何处理数据。由于我正在制作要读取的文件,因此我可以轻松控制格式。谢谢。
  • 这类似于用正则表达式解析 HTML/XML 的流行问题。是的,您可以这样做,但绝不会以对所有可能的 HTML/XML 文件都安全的方式进行。我想如果您控制格式,该方法可能会在一段时间内很好,但是当需要扩展格式时,您会发现自己很快又卡住了。考虑有人使用文本编辑器编辑文件的可能性,这种方式使您的 hackish 解析器无法读取它们,但可以由适当的 XML 解析器读取。如果您真的想使用您正在使用的方法,那么也许其他人可以提供帮助。
  • 虽然我想为任何事件做好准备,但如果有人篡改文件,那是他们的错,为了我了解它是如何工作的,我是会选择无视。如果您仍然认为我不应该费心尝试,请告诉我;你可能会说服我:P(出于好奇,有人弄乱文件会产生 XML 可以读取的东西的可能性有多大,但如果我试图读取标签之间的所有内容,我不能?)跨度>
猜你喜欢
  • 2011-08-11
  • 2010-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-01
  • 2013-08-30
  • 2011-05-31
相关资源
最近更新 更多