/xmlbench/trunk

To get this branch, use:
bzr branch http://darksoft.org/webbzr/xmlbench/trunk
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
#!/usr/bin/ruby

require 'xml'
require 'ftools'

#class Array; def sum; inject( 0 ) { |sum,x| sum+x }; end; end


def calc(node)
    res = Float(node.child.content) rescue 0 if (node.child and node.child.text?())
    return res if (res)
    node.each_attr do |attr|
	res = Float(attr.child.content) rescue 0
	return res if (res)
    end
    return 0
end

def siblings(node)
    res = 0

#    i=0;
#    node.children.each { |cur_node|
#	break if (i+=1)>3
#    }
#    cond = if (i>3); 1 else; nil end
    
    cond = (node.children.length>3)?1:nil;
	
    node.children.each { |cur_node|
	if cur_node.element?
	    if cond
#		res += calc(cur_node)
		val = Float(cur_node.child.content) rescue 0 if (cur_node.child and cur_node.child.text?())
		if (val)
		    res += val
		else
		    cur_node.each_attr do |attr|
			val = Float(attr.child.content) rescue 0
		        if (val)
			    res += val
			    break
			end
		    end
		end
	    end
	    res += siblings(cur_node)
	end
    }
    return res
end

def parse(xml, walk)
#    Does not close a file, complines if many iterations are involved
#    parser = XML::Parser.file(xml)
#    doc = parser.parse

    f = File.new(xml);
    parser = XML::Parser.io(f)
    doc = parser.parse
#    print doc    

    if (walk)
#	This is slowest 330 ms
#	sum = siblings(doc.root)

	sum = 0
#	doc.find("//*[(@* or text()) and (count(../child::*)>3)]").each do |node|


#	nodes = doc.find("//*[(number(@*) or number(text())) and (count(../child::*)>3)]")
#	nodes.each do |node|

	doc.find("//*[count(child::*)>3]/*[number(@*) or number(text())]").each do |node|
#	    190 ms
#	    sum += calc(node)
	    
	    #Fastest approach ~ 177ms

	    res = Float(node.child.content) rescue 0 if (node.child and node.child.text?())
	    if (res)
		sum += res
	    else
		node.each_attr do |attr|
		    res = Float(attr.child.content) rescue 0
		    if (res)
			sum += res
			break
		    end
		end
	    end
	end
#	nodes = nil

=begin
	sum = doc.find("//*[(number(@*) or number(text())) and (count(../child::*)>3)]").map { |node|
	    res = Float(node.child.content) rescue nil if (node.child and node.child.text?())
	    next res if ((res)&&(res!=0))
	    
	    node.each_attr do |attr|
		res = Float(attr.child.content) rescue nil
		break res if ((res)&&(res!=0))
	    end
	}.sum
=end

=begin
	sum = doc.find("//*[(number(@*) or number(text())) and (count(../child::*)>3)]").inject(0) { |sum, node|
	    res = Float(node.child.content) rescue nil if (node.child and node.child.text?())
	    next sum+res if ((res)&&(res!=0))
	    
	    node.each_attr do |attr|
		res = Float(attr.child.content) rescue nil
		break res if ((res)&&(res!=0))
	    end + sum
	}
=end

#	print "Sum: #{sum}\n"
    end
    f.close
end

walk_tree = ENV['walk_tree']

if ($*.length > 0)
    iterations = $*[0].to_i
else
    iterations = 0
end

if ($*.length > 1)
    filename = lambda { |i| $*[1] }
else
    filename = lambda { |i| "../xml.tmp/#{i}.xml" }
end

parse(filename.call(0), walk_tree)

iterations.times { |i|
    parse(filename.call(i+1), walk_tree)
}