How do I do this?

How do I call my code and actually output its data into a file the user can type in, such as Sample.xml ? Here is the code, I didn't make it.

I want to say "What would you like your file to be called?"
USer types: Sample.xml

Then it will create it and put all of my .h and .cpp data in Sample.xml in XML format.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <functional>
#include <map>

#include "Consumable.h"
#include "Equipment.h"
#include "Character.h"
#include "Player.h"
#include "Entity.h"
#include "Armor.h"
#include "Weapon.h"
#include "Item.h"
#include "Creature.h"
#include "XMLSerializable.h"

using namespace std;

XMLSerializable * constructItem()
{
        return new Item;
}


void  outputXML(vector<XMLSerializable*> & vObjects, ostream & output)
{


        output << "<?xml version=\"1.0\" encoding = \"utf-8\"?>"
                << endl
                << "<World>"
                << endl;

        for( auto it = vObjects.begin();
           it != vObjects.end();
           it++ )
vObjects.begin();
        it != vObjects.end();
        it++)
{
        (*it)->dumpObject();
        cout << endl;
}

}

void parseElement(istream & input, string sPrefix)
{
        string sElementName;
        getline(input, sElementName, '>');

        if( sElementName.back() == '/' )
        {
                cout << sPrefix << "Empty element: " << sElementName << endl;
                return;
        }
        else
        {
                cout << sPrefix << "Element - " << sElementName << endl;
        }

        string sContent = "";



        while( true )
        {

                char c = input.get();

                while( c != '<' )
                {
                        if( c != '\n' )
                                sContent.push_back(c);

                        c = input.get();
                }

                if( input.peek() == '/' )
                {
                        input.get();
                        string sEndElement;
                        getline(input, sEndElement, '>');

                        if( sEndElement != sElementName )
                                cout << "Bad XML found" << endl;


                        cout << sPrefix << "Content - " << sContent << endl;

                        return;
                }
                else
                {
                        parseElement(input, sPrefix + "  ");
                }

        }

}

void parseXML(string sFilename)
{
        ifstream input;
        input.open(sFilename);

        while( input.get() != '?' );
        while( input.get() != '?' );

        if( input.get() != '>' )
        {
                cout << "Bad XML detected" << endl;
                return;
        }

        while( input.get() != '<' );


        parseElement(input, "");

}



int main(int argc, char * argv[])
{




        map<string, function<XMLSerializable*()> > mapConstructor;

        mapConstructor["Item"] = []() {return new Item; };

        mapConstructor["Weapon"] = []() { return new Weapon; };
        mapConstructor["Armor"] = []() { return new Armor; };
        mapConstructor["Creature"] = []() { return new Creature; };

        string sLookup;
cout << "What class do you want to look up? " << endl;
        cin >> sLookup;

        function<XMLSerializable*()> pFunc = mapConstructor[sLookup];



        if(pFunc == NULL)
        {
          cout << "Class" << sLookup << " not found. " << endl;
        }
        else
        {
          XMLSerializable * pObject = pFunc();

                if (pObject == NULL)
                {
                        cout << "Couldn't construct object. " << endl;
                }
                else
                {
                        cout << "Object constructed." << endl;
                }

        }

        cout << "What would you like your XML file to be named?" << endl;

        //void outputXML(vector<XMLSerializable*> & vObjects, ostream & output);
        //cin >> &output;



        cout << "What file should we parse? ";
        string sFilename;
        cin >> sFilename;
 parseXML(sFilename);



        return 0;
}


Not sure I follow, do you mean something like
1
2
3
4
string outputFileName("");
cout << "What would you like your XML file to be named?" << endl;
cin >> outputFileName;
ofstream outputFile(outputFileName.c_str());

and then pass outputFile as your ostream & to ouputXML()? You'd also have to somehow connect it with XMLSerializable::dumpObject()...

Exactly! Yes how would I do that? right now I have..

1
2
3
4
5
        string outputFileName("");
        cout << "What would you like your XML file to be named?" << endl;
        cin >> outputFileName;
        ofstream outputXML(outputFileName.c_str());
Last edited on
Can we see the code fro XMLSerializable::dumpObject()?
XMLSerializable.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#ifndef _XMLSerializable_included_
#define _XMLSerializable_included_

#include <iostream>
#include <ostream>
#include <string>

class XMLSerializable
{
public:
        virtual void dumpObject() = 0;
        virtual void dumpObjectData()= 0;
        virtual void writeFragment(std::ostream & output) = 0;
        virtual void writeDataAsFragment(std::ostream & output) = 0;
        virtual void setElementData(std::string sElementName, std::string sValue) = 0;
};


#endif 

Also here is what it actually does in the Entity.cpp file that inherits from the XML base class. (NOTE: not all of the code in Entity.cpp) Entity.cpp is connected to Entity.h which inherits from XMLSerializable.h

1
2
3
4
5
6
7
8
9
10
11
void Entity::dumpObjectData()
{
        cout << "   Name : " << getName() << endl;
        cout << " Symbol : " << getSymbol() << endl;
}
void Entity::dumpObject()
{
        cout << "Entity: " << endl;

        dumpObjectData();
}
Last edited on
I'm sorta shooting in the dark here, so apologies in advance.

As far as dumpObject goes, it appears you are tied into cout, if you are allowed to change the code, maybe add an ofstream member, initalise it with ofstream::open (outputFileName) and use it instead of cout.

Although it souds to me like dumpObject is intended to be a debug tool and functions:
1
2
virtual void writeFragment(std::ostream & output) = 0;
virtual void writeDataAsFragment(std::ostream & output) = 0;

are looking very interesting indeed. I can easily see a scenario like:
(*it)->writeFragment(outputXML); replacing the line 43 in the loop in your first code post above.

Did you see what my outputXML function is doing in line 27? I'm not sure if I would need to worry about cout.
outputXML writes 2 lines ("<?xml version=\"1.0\" encoding = \"utf-8\"?>" and "<World>") to the ostream& it's given, then repeatedly calls dumpObject, which calls dumpObjectData, which both ultimately write to cout.

My understanding was that you want that output in your user supplied output file instead of on cout
Well let's forget that idea. Let's just say I want to cout my data...How would I do that??
Any idea?
Topic archived. No new replies allowed.