LebGeeks

A community for technology geeks in Lebanon.

You are not logged in.

#1 December 30 2011

xterm
Moderator

[Exercise] Vanilla XML Builder

With the language of your choice, create an XML Builder that adheres to the vanilla rules of XML.

Semi Pseudo

auditorium = Node(tag: "Auditorium")

john  = Node(tag="Person", attr={ name: "john", sex: "male"})
jane  = Node(tag="Person", attr={ name: "jane", sex: "female"})
rahmu = Node(tag="Person", attr={ name: "rahmu", sex: "undetermined"})

auditorium.children.add([john,jane,rahmu])

auditorium.flush(out_stream)

Output

<Auditorium>
<Person name="john" sex="male"/>
<Person name="jane" sex="female"/>
<Person name="rahmu" sex="undetermined"/>
</Auditorium>

Use anything at your disposal.

Offline

#2 December 30 2011

samer
Admin

Re: [Exercise] Vanilla XML Builder

The code could look much better and needs some checks, it could be much more efficient and elegant as well.
It's doing the job, so I'm guessing that should count for something.

The assumption is that the tags will self-close when they don't have children.

Ruby

class Node
    
    attr_accessor :tag, :attr, :children
    
    def initialize( tag, attr )
        @tag = tag
        @attr = attr
        self.children = []
    end
    
    def add_children( children )
        # add check to make sure they are nodes
        children.each do |c|
            self.children << c
        end
    end
    
    def has_children?
        self.children != [] ? true : false
    end
    
    def print_all
        
       if self.has_children? == true
           self.print_open( true )
           self.children.each do |c|
               c.print_all
           end
           self.print_close
       else
           self.print_open( false )
       end 
    end
    
    def print_open( children_flag )
        if self.attr != {}
            print "<#{tag} "
            self.attr.each{ |k,v| print "#{k}=\"#{v}\" " }
            print children_flag ? ">\n" : "/>\n"
        else
            puts children_flag ? "<#{tag}>" : "<#{tag} />"
        end
    end
    
    def print_close
        puts "</#{tag}>"
    end
    
end

auditorium = Node.new( "Auditorium", {} )

roula = Node.new( "Person", { :name => "roula", :sex => "female" } )
omar = Node.new( "Person", { :name => "omar", :sex => "male" } )
raul = Node.new( "Baby", { :name => "raul", :sex => "male" })

auditorium.add_children( [roula, omar] )
omar.add_children( [raul] )
auditorium.print_all
<Auditorium>
<Person name="roula" sex="female" />
<Person name="omar" sex="male" >
<Baby name="raul" sex="male" />
</Person>
</Auditorium>

Offline

#3 December 30 2011

geek
Member

Re: [Exercise] Vanilla XML Builder

function Node(tag, attr) {
	this.tag = tag;
	this.attr = attr;
	this.children = [];
}

Node.prototype.print = function () {
	print(this.xml_string());
};

Node.prototype.xml_string = function () {
	var attr_string = function (attr) {
		var s = '';
		for (var a in attr) {
			s += ' ' + a + '="' + attr[a] + '"';
		}
		return s;
	};

	var s = '';
	if (this.children.length > 0) {
		s += '<' + this.tag +  attr_string(this.attr) + '>';
		for (var i = 0; i < this.children.length; i++) {
			s += this.children[i].xml_string();
		}
		s += '</' + this.tag + '>';
	} else {
		s += '<' + this.tag +  attr_string(this.attr) + '/>';
	}
	return s;
};

var group = new Node('group', {});
group.children.push(new Node('person', {name: 'foo', sex: 'm'}));
group.children.push(new Node('person', {name: 'bar', sex: 'f'}));
group.children.push(new Node('person', {name: 'baz', sex: 'z'}));
group.children.push(new Node('person', {name: 'qux', sex: 'u'}));
group.print();

Offline

#4 December 30 2011

arithma
Member

Re: [Exercise] Vanilla XML Builder

Shouldn't we use some language descriptor: Ruby and JS for the above examples?

Offline

#5 December 30 2011

xterm
Moderator

Re: [Exercise] Vanilla XML Builder

samer,

It works, but with ruby's language feature you should do better. Try to implement it using the builder concept, it would look awesome.

As in, write the builder.

Offline

#6 December 30 2011

samer
Admin

Re: [Exercise] Vanilla XML Builder

xterm wrote:

samer,

It works, but with ruby's language feature you should do better. Try to implement it using the builder concept, it would look awesome.

As in, write the builder.

It seems that the method_missing could do the trick to pull something like this off:

Ruby

builder = Builder.new( … )
builder.auditorium{ |build|
  build.name("Omar");
  build.gender("Male");
}

I'll try to work on it, ASAP.

Offline

#7 December 30 2011

CSGeek
Member

Re: [Exercise] Vanilla XML Builder

Vanilla rules of XML...  what's that?  You got me confused now after failing to look it up on Google!

I read the XML you posted 'normal'.

Correct me please! or provide some definition for what you call Vanilla rules of XML.

Offline

#8 December 31 2011

xterm
Moderator

Re: [Exercise] Vanilla XML Builder

Vanilla = Normal.

Offline

Board footer