开发者

RapidXML throwing a parse_error exception

When I try to parse a simple .xml file using the RapidXML framework, it throws a parse_error with this cause: "expected <". Now this is practically my first time writing XML code, so it might be a silly syntax error, in that case, bear with me :) This is my xmlParser.h:

#ifndef __XML_PARSER_H__
#define __XML_PARSER_H__开发者_Go百科

#include "rapidxml.hpp"
#include "windowUtil.h"

class XmlParser
{
public:
    bool parse(char *xml)
    {
        try
        {
            doc.parse<0>(xml);
        }
        catch(rapidxml::parse_error &e)
        {
            msg_box(NULL, e.what(), "RapidXML exception!", MB_OK | MB_ICONERROR | MB_TASKMODAL);

            return false;
        }

        return true;
    }

    char* get_first_node_name()
    {
        return doc.first_node()->name();
    }
private:
    rapidxml::xml_document<> doc;
};

#endif

And this is how it is called and used:

int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow)
{
    XmlParser xmlParser;
    WindowFramework *window = create_window(&framework, NULL, NULL, "GAME");

    if(!init_window(window, true, true))
        return kill(1);
    if(!xmlParser.parse("./layouts/login_gui.xml"))
        return kill(1);

    framework.main_loop();

    return kill(0);
}

login_gui.xml:

<?xml version="1.0"?>
<button>
    <text>EXIT</text>
    <buttonready>button.png</buttonready>
    <buttonrollover>button_active.png</buttonrollover>
    <buttonpressed>button_pressed.png</buttonpressed>
    <buttoninactive>button_inactive.png</buttoninactive>
</button>


The parse method takes a string containing XML, you are passing it a filename. Your filename is being treated as the XML data and obviously that's not right. You must read in the file first, and then call parse with the resulting string.

From the RapidXML docs:

function xml_document::parse

Synopsis

void parse(Ch *text); 

Description

Parses zero-terminated XML string according to given flags.

Your revised structure could be something like

bool parse(char *xmlFile)        
{            
     try            
     {  
        std::string xml(getXmlDataFromFile(xmlFile));
        doc.parse<0>(xml.c_str());            
     }  


There's a fine document on using RapidXML that I always refer to. It's a must read!

Here is my attempt to read the first nodes of your document (demo.xml).

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]);

// we didn't keep track of our previous traversal, so let's start again
// we can match nodes by name, skipping the xml declaration entirely
xml_node<>* cur_node = doc.first_node("button");

// go straight to the first text node
cur_node = cur_node->first_node("text");
string text = cur_node->value(); // if the node doesn't exist, this line will crash
cout << text << endl;

// and then to the next node
cur_node = cur_node->next_sibling("buttonready");
string b_ready = cur_node->value();
cout << b_ready << endl;

// and then to the next node
// ...

Outputs:

EXIT
button.png

If in the future your XML gets more complex, you could take a look at this answer:

Read a line from xml file using C++

which shows a source code that also read properties from nodes.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜