XML generator

Hi.
I want to create a simple xml generator.(I don't want to use 3rd party codes)
I created the code below:
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
#include <iostream>
#include <fstream>
using namespace std;

ofstream file;

class Node
{
	public:
		Node(int id)
		{
			ID = id;
			file << "<Node " << ID << ">\n";
			
			for(int i = 0; i <= ID; i++)
				file << ' ';
		}
		~Node()
		{
			file << "</Node " << ID << ">\n";
		}
	private:
		int ID;
};

int main()
{
	file.open("created.txt", ios::out);
	
	Node* n0 = new Node(0);
	Node* n1 = new Node(1);
	delete n1;
	Node* n2 = new Node(2);
	Node* n3 = new Node(3);
	delete n3;
	delete n2;
	
	delete n0;
}


Is there a better way to do this?
This code creates following file:
<Node 0>
 <Node 1>
  </Node 1>
<Node 2>
   <Node 3>
    </Node 3>
</Node 2>
</Node 0>
Is there a better way to do this?
Yes, make your own print function. Like so:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
		Node(int id)
		{
			ID = id;
			PrintHead(false);
		}
		~Node()
		{
			PrintHead(true);
		}
...
		PrintHead(bool end)
		{
			for(int i = 0; i <= ID; i++)
				file << ' ';
			file << "<";
			if(end)
				file << "/";
			file << "Node " << ID << ">\n";
		}			
In your way, I do not need to use pointers? correct?
Yes, you don't need pointer. PrintHead() is a function like the constructor. You need the pointer if you want to call the function from outside the class

The constructor has a special trait. You can write it like so:
1
2
3
4
		Node(int id) : ID(id)
		{
			PrintHead(false);
		}


Node(int id) : ID(id) is called initializer list. It's the way to call the constructors of the member variables (and may avoid unnecessary copy)
In this way (putting start and end tags in constructor and destructor) I don't have control over where to put them. Isn't it better to create to public function and do tag insertion in it? I mean I make PrintHead function public and don't use them in constructor/destructor.
I mean I make PrintHead function public and don't use them in constructor/destructor.
Sure, feel free to do so. You access the function like so:n0->PrintHead(...)

You might want to pass an additional parameter ostream &os, so that you can print it to any output (such as cout)
That's not healthy.

Implement a forest as a collection of trees.
Recurse the printing.
Excuse me, I didn't understand. Please explain.
Thanks.
For what you show `0' is the parent of `1' and `2', that could be easily represented with a tree.
You need to finish the inner nodes before the outer, that suggest a pre-order traversal.

The way you are doing it is too error prone.
So this is not a binary tree and is not in STL.
how can I implement a tree with variable number of children?
Are you just trying to create a random XML file (like you show above), or do you need to create a tree of C++ nodes for use later?

If the former, I'd do as ne555 suggests and use recursion.

For each node:
- print out start tag
- decide how many children
- call function for each child node
- print out end tag

You just need one function to generate the XML fragment you posted!

Andy

PS Remember that XML tag names cannot contain spaces!
http://www.w3schools.com/xml/xml_elements.asp
Last edited on
I haven't used C++ to do XML, but I did have fun playing with outputting HTML pages with it out of pure boredom. Honestly, it sounds like it is being made more complex than it need be to me though.
Topic archived. No new replies allowed.