fabulator 0.0.8 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +30 -1
- data/VERSION +1 -1
- data/features/functions.feature +7 -0
- data/features/primitives.feature +1 -1
- data/features/step_definitions/template_steps.rb +40 -3
- data/features/step_definitions/xml_steps.rb +3 -2
- data/features/templates.feature +49 -22
- data/features/types.feature +4 -4
- data/lib/fabulator.rb +4 -0
- data/lib/fabulator/compiler.rb +27 -0
- data/lib/fabulator/core.rb +3 -8
- data/lib/fabulator/core/actions/choose.rb +0 -18
- data/lib/fabulator/core/actions/for_each.rb +0 -48
- data/lib/fabulator/core/{actions.rb → lib.rb} +189 -117
- data/lib/fabulator/core/structurals.rb +7 -0
- data/lib/fabulator/core/{constraint.rb → structurals/constraint.rb} +2 -0
- data/lib/fabulator/core/{filter.rb → structurals/filter.rb} +2 -0
- data/lib/fabulator/core/{group.rb → structurals/group.rb} +2 -0
- data/lib/fabulator/core/{parameter.rb → structurals/parameter.rb} +2 -0
- data/lib/fabulator/core/{state.rb → structurals/state.rb} +2 -0
- data/lib/fabulator/core/{state_machine.rb → structurals/state_machine.rb} +2 -0
- data/lib/fabulator/core/{transition.rb → structurals/transition.rb} +2 -0
- data/lib/fabulator/expr.rb +6 -0
- data/lib/fabulator/expr/context.rb +65 -10
- data/lib/fabulator/expr/node_logic.rb +3 -2
- data/lib/fabulator/expr/parser.rb +787 -638
- data/lib/fabulator/expr/statement_list.rb +27 -0
- data/lib/fabulator/lib.rb +3 -0
- data/lib/fabulator/lib/action.rb +12 -9
- data/lib/fabulator/lib/lib.rb +85 -9
- data/lib/fabulator/structural.rb +24 -5
- data/lib/fabulator/tag_lib.rb +78 -124
- data/lib/fabulator/tag_lib/presentations.rb +39 -0
- data/lib/fabulator/tag_lib/transformations.rb +66 -0
- data/lib/fabulator/tag_lib/type.rb +176 -0
- data/lib/fabulator/template/parse_result.rb +125 -62
- data/lib/fabulator/template/parser.rb +17 -1
- data/xslt/form.xsl +163 -2083
- data/xsm_expression_parser.racc +35 -20
- metadata +17 -13
- data/lib/fabulator/context.rb +0 -39
@@ -0,0 +1,39 @@
|
|
1
|
+
module Fabulator
|
2
|
+
class TagLib
|
3
|
+
class Presentations
|
4
|
+
def initialize
|
5
|
+
@transformations = Fabulator::TagLib::Transformations.new
|
6
|
+
@interactives = { }
|
7
|
+
@structurals = { }
|
8
|
+
end
|
9
|
+
|
10
|
+
def transformations_into
|
11
|
+
@transformations
|
12
|
+
end
|
13
|
+
|
14
|
+
def interactives
|
15
|
+
@interactives.keys
|
16
|
+
end
|
17
|
+
|
18
|
+
def structurals
|
19
|
+
@structurals.keys
|
20
|
+
end
|
21
|
+
|
22
|
+
def interactive(nom)
|
23
|
+
@interactives[nom.to_sym] = nil
|
24
|
+
end
|
25
|
+
|
26
|
+
def structural(nom)
|
27
|
+
@structurals[nom.to_sym] = nil
|
28
|
+
end
|
29
|
+
|
30
|
+
def transform(fmt, doc, opts = { })
|
31
|
+
@transformations.transform(fmt, doc, opts)
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_root_namespaces(fmt)
|
35
|
+
@transformations.get_root_namespaces(fmt)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'xml/libxml'
|
2
|
+
require 'libxslt'
|
3
|
+
|
4
|
+
module Fabulator
|
5
|
+
class TagLib
|
6
|
+
class Transformations
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@formats = { }
|
10
|
+
end
|
11
|
+
|
12
|
+
def html(&block)
|
13
|
+
@formats[:html] ||= Fabulator::TagLib::Format.new
|
14
|
+
@formats[:html].instance_eval &block
|
15
|
+
end
|
16
|
+
|
17
|
+
def transform(fmt, doc, opts = { })
|
18
|
+
if !@formats[fmt.to_sym].nil?
|
19
|
+
@formats[fmt.to_sym].transform(doc, opts)
|
20
|
+
else
|
21
|
+
doc
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_root_namespaces(fmt)
|
26
|
+
if !@formats[fmt.to_sym].nil?
|
27
|
+
@formats[fmt.to_sym].get_root_namespaces
|
28
|
+
else
|
29
|
+
[]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class Format
|
35
|
+
def initialize
|
36
|
+
end
|
37
|
+
|
38
|
+
def transform(doc, opts)
|
39
|
+
if !@xslt.nil?
|
40
|
+
@xslt.apply(doc, opts)
|
41
|
+
else
|
42
|
+
doc
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def xslt_from_file(fpath)
|
47
|
+
@xslt_file = fpath
|
48
|
+
@xslt_doc = LibXML::XML::Document.file(@xslt_file)
|
49
|
+
@xslt = LibXSLT::XSLT::Stylesheet.new(@xslt_doc)
|
50
|
+
end
|
51
|
+
|
52
|
+
def get_root_namespaces
|
53
|
+
if !@xslt_doc.nil?
|
54
|
+
# extract namespace declarations from root element
|
55
|
+
ret = [ ]
|
56
|
+
@xslt_doc.root.namespaces.each { |ns|
|
57
|
+
ret << ns.href
|
58
|
+
}
|
59
|
+
ret
|
60
|
+
else
|
61
|
+
[]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,176 @@
|
|
1
|
+
module Fabulator
|
2
|
+
class TagLib
|
3
|
+
class Type
|
4
|
+
def initialize(t)
|
5
|
+
@type = t
|
6
|
+
@goings = { }
|
7
|
+
@comings = { }
|
8
|
+
@methods = { }
|
9
|
+
end
|
10
|
+
|
11
|
+
def vtype
|
12
|
+
@type
|
13
|
+
end
|
14
|
+
|
15
|
+
def going_to(t, &block)
|
16
|
+
return unless block
|
17
|
+
@goings[t.join('')] ||= [ ]
|
18
|
+
obj = TypeConversion.new(t)
|
19
|
+
obj.instance_eval &block
|
20
|
+
@goings[t.join('')] = obj
|
21
|
+
end
|
22
|
+
|
23
|
+
def coming_from(t, &block)
|
24
|
+
return unless block
|
25
|
+
@comings[t.join('')] ||= [ ]
|
26
|
+
obj = TypeConversion.new(t)
|
27
|
+
obj.instance_eval &block
|
28
|
+
@comings[t.join('')] = obj
|
29
|
+
end
|
30
|
+
|
31
|
+
def outgoing_conversions
|
32
|
+
@goings
|
33
|
+
end
|
34
|
+
|
35
|
+
def incoming_conversions
|
36
|
+
@comings
|
37
|
+
end
|
38
|
+
|
39
|
+
def method(nom, &block)
|
40
|
+
@methods[@type[0] + nom.to_s] = block
|
41
|
+
end
|
42
|
+
|
43
|
+
def get_method(nom)
|
44
|
+
@methods[nom]
|
45
|
+
end
|
46
|
+
|
47
|
+
def build_conversion_to(to)
|
48
|
+
return [] if to.nil? || self == to
|
49
|
+
ut = self._unify_types(to, true)
|
50
|
+
return [] if ut.nil? || ut[:t].join('') != to.join('')
|
51
|
+
return ut[:convert]
|
52
|
+
end
|
53
|
+
|
54
|
+
def unify_with_type(t)
|
55
|
+
self._unify_types(t)
|
56
|
+
end
|
57
|
+
|
58
|
+
protected
|
59
|
+
|
60
|
+
def _unify_types(to, ordered = false)
|
61
|
+
return nil if to.nil?
|
62
|
+
if to.is_a?(Array)
|
63
|
+
to = Fabulator::TagLib.type_handler(to)
|
64
|
+
return nil if to.nil?
|
65
|
+
end
|
66
|
+
|
67
|
+
d1 = { @type.join('') => { :t => self, :w => 1.0, :path => [ self ], :convert => [ ] } }
|
68
|
+
d2 = { to.vtype.join('') => { :t => to, :w => 1.0, :path => [ to ], :convert => [ ] } }
|
69
|
+
|
70
|
+
added = true
|
71
|
+
while added
|
72
|
+
added = false
|
73
|
+
[d1, d2].each do |d|
|
74
|
+
d.keys.each do |t|
|
75
|
+
d[t][:t].outgoing_conversions.each_pair do |conv_key, conv|
|
76
|
+
#conv_key = conv.vtype.join('')
|
77
|
+
w = d[t][:w] * conv.weight
|
78
|
+
if d.has_key?(conv_key)
|
79
|
+
if d[conv_key][:w] < w
|
80
|
+
d[conv_key][:w] = w
|
81
|
+
d[conv_key][:path] = d[t][:path] + [ conv.vtype ]
|
82
|
+
d[conv_key][:convert] = d[t][:convert] + [ conv ] - [nil]
|
83
|
+
end
|
84
|
+
else
|
85
|
+
added = true
|
86
|
+
d[conv_key] = {
|
87
|
+
:t => conv.vtype,
|
88
|
+
:w => w,
|
89
|
+
:path => d[t][:path] + [ conv.vtype ],
|
90
|
+
:convert => d[t][:convert] + [ conv ] - [nil],
|
91
|
+
}
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
Fabulator::TagLib.types.keys.each do |ns|
|
96
|
+
Fabulator::TagLib.types[ns].each_pair do |ct, tob|
|
97
|
+
to_key = ns + ct.to_s
|
98
|
+
tob.incoming_conversions.each_pair do |from_key, conv|
|
99
|
+
#from_key = conv.vtype.join('')
|
100
|
+
next unless d.has_key?(from_key)
|
101
|
+
w = d[from_key][:w] * conv.weight
|
102
|
+
if d.has_key?(to_key)
|
103
|
+
if d[to_key][:w] < w
|
104
|
+
d[to_key][:w] = w
|
105
|
+
d[to_key][:path] = d[from_key][:path] + [ conv.vtype ]
|
106
|
+
d[to_key][:convert] = d[from_key][:convert] + [ conv ]
|
107
|
+
end
|
108
|
+
else
|
109
|
+
added = true
|
110
|
+
d[to_key] = {
|
111
|
+
:t => [ ns, ct ],
|
112
|
+
:w => w * 95.0 / 100.0,
|
113
|
+
:path => d[from_key][:path] + [ conv.vtype ],
|
114
|
+
:convert => d[from_key][:convert] + [ conv ],
|
115
|
+
}
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
r = self._select_type_path(d1, d2, to, ordered)
|
122
|
+
return r unless r.nil?
|
123
|
+
end
|
124
|
+
return self._select_type_path(d1, d2, to, ordered)
|
125
|
+
end
|
126
|
+
|
127
|
+
def _select_type_path(d1, d2, t2, ordered)
|
128
|
+
common = d1.keys & d2.keys
|
129
|
+
if ordered && common.include?(t2.vtype.join(''))
|
130
|
+
return d1[t2.vtype.join('')]
|
131
|
+
elsif !common.empty?
|
132
|
+
return d1[common.sort_by{ |c| d1[c][:w] * d2[c][:w] / d1[c][:path].size / d2[c][:path].size }.reverse.first]
|
133
|
+
end
|
134
|
+
return nil
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
class TypeConversion
|
140
|
+
def initialize(t)
|
141
|
+
@type = t
|
142
|
+
@weight = 0.0
|
143
|
+
# @guard = nil
|
144
|
+
end
|
145
|
+
|
146
|
+
def vtype
|
147
|
+
@type
|
148
|
+
end
|
149
|
+
|
150
|
+
def weight(w = nil)
|
151
|
+
@weight = w unless w.nil?
|
152
|
+
@weight
|
153
|
+
end
|
154
|
+
|
155
|
+
# def guard(&block)
|
156
|
+
# if !block.nil?
|
157
|
+
# @guard = block
|
158
|
+
# end
|
159
|
+
# end
|
160
|
+
|
161
|
+
def converting(&block)
|
162
|
+
@conversion = block
|
163
|
+
end
|
164
|
+
|
165
|
+
def convert(v)
|
166
|
+
return v.root.anon_node(nil) if @conversion.nil?
|
167
|
+
@conversion.call(v)
|
168
|
+
end
|
169
|
+
|
170
|
+
# def can_convert?(v)
|
171
|
+
# return true if @guard.nil?
|
172
|
+
# @guard.call(v)
|
173
|
+
# end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
@@ -1,20 +1,67 @@
|
|
1
1
|
require 'xml/libxml'
|
2
|
-
require 'libxslt'
|
3
2
|
|
4
3
|
module Fabulator::Template
|
5
4
|
class ParseResult
|
6
5
|
|
7
|
-
|
6
|
+
def initialize(text)
|
7
|
+
## we want to build up the XPath expression for structural and
|
8
|
+
## interactive elements for use in adding default info and
|
9
|
+
## building names for those elements -- saves the XSLT from having
|
10
|
+
## to do this
|
8
11
|
|
12
|
+
structurals = { }
|
13
|
+
interactives = { }
|
9
14
|
|
10
|
-
|
11
|
-
|
15
|
+
Fabulator::TagLib.namespaces.each_pair do |ns, ob|
|
16
|
+
structurals[ns] = ob.presentation.structurals
|
17
|
+
interactives[ns] = ob.presentation.interactives
|
18
|
+
end
|
12
19
|
|
20
|
+
@namespaces = { }
|
21
|
+
i = 1
|
22
|
+
(structurals.keys + interactives.keys).uniq.sort.each do |ns|
|
23
|
+
@namespaces["fab_ns_#{i.to_s}"] = ns
|
24
|
+
i += 1
|
25
|
+
end
|
26
|
+
|
27
|
+
structural_xpaths = []
|
28
|
+
interactive_xpaths = []
|
29
|
+
interesting_xpaths = [ ]
|
30
|
+
@fab_prefix = ''
|
31
|
+
@namespaces.keys.each do |p|
|
32
|
+
@fab_prefix = p if @namespaces[p] == Fabulator::FAB_NS
|
33
|
+
structural_xpaths += structurals[@namespaces[p]].collect{ |e| "ancestor::#{p}:#{e}" }
|
34
|
+
interactive_xpaths += interactives[@namespaces[p]].collect{ |e| "//#{p}:#{e}" }
|
35
|
+
interesting_xpaths += structurals[@namespaces[p]].collect{ |e| "//#{p}:#{e}" }
|
36
|
+
end
|
37
|
+
@structural_xpath = structural_xpaths.join("[@id != ''] | ") + "[@id != '']"
|
38
|
+
@interactive_xpath = interactive_xpaths.join(" | ")
|
39
|
+
|
40
|
+
@interesting_xpath = (interactive_xpaths + interesting_xpaths).join(" | ")
|
41
|
+
|
42
|
+
@namespaces = @namespaces.collect{ |k,v| "#{k}:#{v}" }
|
43
|
+
|
44
|
+
## We also may do our dependency tree -- namespaces in the
|
45
|
+
## root element of the stylesheet will be run after the current
|
46
|
+
## stylesheet
|
13
47
|
|
14
|
-
def initialize(text)
|
15
48
|
@doc = LibXML::XML::Document.string text
|
49
|
+
|
50
|
+
@fab_ns = nil
|
51
|
+
@doc.root.namespaces.each do |ns|
|
52
|
+
if ns.href == Fabulator::FAB_NS
|
53
|
+
@fab_ns = ns
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
if @fab_ns.nil?
|
58
|
+
@fab_ns = XML::Namespace.new(@doc.root, @fab_prefix, Fabulator::FAB_NS)
|
59
|
+
end
|
16
60
|
end
|
17
61
|
|
62
|
+
# This function walks through all of the elements in the provided
|
63
|
+
# markup and adds f:default child elements. TagLibs declare data
|
64
|
+
# elements that should receive default values.
|
18
65
|
def add_default_values(context)
|
19
66
|
return if context.nil?
|
20
67
|
each_form_element do |el|
|
@@ -22,13 +69,7 @@ module Fabulator::Template
|
|
22
69
|
next if own_id.nil? || own_id.to_s == ''
|
23
70
|
|
24
71
|
default = nil
|
25
|
-
|
26
|
-
if el.name == 'grid'
|
27
|
-
default = el.find('./default | ./row/default | ./column/default').to_a
|
28
|
-
is_grid = true
|
29
|
-
else
|
30
|
-
default = el.find('./default').to_a
|
31
|
-
end
|
72
|
+
default = el.find("./#{@fab_prefix}:default", @namespaces).to_a
|
32
73
|
|
33
74
|
id = el_id(el)
|
34
75
|
ids = id.split('/')
|
@@ -37,31 +78,8 @@ module Fabulator::Template
|
|
37
78
|
if !default.nil? && !default.empty?
|
38
79
|
default.each { |d| d.remove! }
|
39
80
|
end
|
40
|
-
|
41
|
-
|
42
|
-
how_many = 'multiple'
|
43
|
-
direction = 'both'
|
44
|
-
if count =~ %r{^(multiple|single)(-by-(row|column))?$}
|
45
|
-
how_many = $1
|
46
|
-
direction = $3 || 'both'
|
47
|
-
end
|
48
|
-
if direction == 'both'
|
49
|
-
l.collect{|ll| ll.value}.each do |v|
|
50
|
-
el << text_node('default', v)
|
51
|
-
end
|
52
|
-
elsif direction == 'row' || direction == 'column'
|
53
|
-
el.find("./#{direction}").each do |div|
|
54
|
-
id = (div.attributes['id'].to_s rescue '')
|
55
|
-
next if id == ''
|
56
|
-
l.collect{|c| context.with_root(c).traverse_path(id)}.flatten.collect{|c| c.value}.each do |v|
|
57
|
-
div << text_node('default', v)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
else
|
62
|
-
l.collect{|ll| ll.value}.each do |v|
|
63
|
-
el << text_node('default', v)
|
64
|
-
end
|
81
|
+
l.collect{|ll| ll.value}.each do |v|
|
82
|
+
el << text_node('default', v)
|
65
83
|
end
|
66
84
|
end
|
67
85
|
end
|
@@ -92,7 +110,7 @@ module Fabulator::Template
|
|
92
110
|
end
|
93
111
|
|
94
112
|
def add_captions(captions = { })
|
95
|
-
|
113
|
+
each_element do |el|
|
96
114
|
id = el_id(el)
|
97
115
|
next if id == ''
|
98
116
|
caption = nil
|
@@ -107,7 +125,7 @@ module Fabulator::Template
|
|
107
125
|
is_grid = false
|
108
126
|
if el.name == 'grid'
|
109
127
|
else
|
110
|
-
cap = el.find_first(
|
128
|
+
cap = el.find_first("./#{@fab_prefix}:caption", @namespaces)
|
111
129
|
if cap.nil?
|
112
130
|
el << text_node('caption', caption)
|
113
131
|
else
|
@@ -120,56 +138,101 @@ module Fabulator::Template
|
|
120
138
|
end
|
121
139
|
|
122
140
|
def to_s
|
123
|
-
@doc.to_s
|
141
|
+
@doc.to_s.gsub(/^\s*<\?xml\s+.*?\?>\s*/, '')
|
124
142
|
end
|
125
143
|
|
126
144
|
def to_html(popts = { })
|
127
|
-
opts = { :form => true }.update(popts)
|
145
|
+
opts = { :form => true, :theme => 'coal' }.update(popts)
|
146
|
+
|
147
|
+
deps = { }
|
148
|
+
Fabulator::TagLib.namespaces.each_pair do |ns, ob|
|
149
|
+
deps[ns] = ob.presentation.get_root_namespaces(:html) & (Fabulator::TagLib.namespaces.keys) - [ ns ]
|
150
|
+
end
|
151
|
+
|
152
|
+
ordered_ns = [ ]
|
153
|
+
|
154
|
+
next_round = ([ Fabulator::FAB_NS ] + deps.keys.select { |k| deps[k].empty? }).uniq
|
128
155
|
|
129
|
-
|
156
|
+
while !next_round.empty? do
|
157
|
+
next_round.each { |k| deps.delete(k) }
|
158
|
+
|
159
|
+
ordered_ns += next_round
|
160
|
+
|
161
|
+
deps.keys.each do |k|
|
162
|
+
deps[k] -= ordered_ns
|
163
|
+
end
|
164
|
+
|
165
|
+
next_round = deps.keys.select{ |k| deps[k].empty? }
|
166
|
+
end
|
130
167
|
|
168
|
+
ordered_ns.reverse!
|
169
|
+
|
170
|
+
res = @doc
|
171
|
+
ordered_ns.each do |ns|
|
172
|
+
ob = Fabulator::TagLib.namespaces[ns]
|
173
|
+
next if ob.nil?
|
174
|
+
res = ob.presentation.transform(:html, res, opts)
|
175
|
+
end
|
176
|
+
|
177
|
+
ret = ''
|
131
178
|
if opts[:form]
|
132
|
-
res.to_s
|
179
|
+
ret = res.to_s.gsub(/^\s*<\?xml\s+.*?\?>\s*/, '').gsub(/xmlns(:\S+)?=['"][^'"]*['"]/, '').gsub(/\s+/, ' ').gsub(/\s+>/, '>')
|
133
180
|
else
|
134
|
-
res.find('//form/*').collect{ |e| e.to_s}.join('')
|
181
|
+
ret = res.find('//form/*').collect{ |e| e.to_s}.join('').gsub(/^\s*<\?xml\s+.*?\?>\s*/, '').gsub(/xmlns(:\S+)?=['"][^'"]*['"]/, '').gsub(/\s+/, ' ').gsub(/\s+>/, '>')
|
182
|
+
|
135
183
|
end
|
184
|
+
|
185
|
+
ret.gsub!(/<(div\s*[^<]*?)\/>/, "<\\1></div>")
|
186
|
+
ret.gsub!(/<(span\s*[^<]*?)\/>/, "<\\1></span>")
|
187
|
+
ret
|
136
188
|
end
|
137
189
|
|
138
190
|
protected
|
139
191
|
|
192
|
+
def each_element(&block)
|
193
|
+
@doc.root.find(@interesting_xpath, @namespaces).each do |el|
|
194
|
+
yield el
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
140
198
|
def each_form_element(&block)
|
141
|
-
@doc.root.find(
|
142
|
-
//text
|
143
|
-
| //textline
|
144
|
-
| //textbox
|
145
|
-
| //editbox
|
146
|
-
| //asset
|
147
|
-
| //password
|
148
|
-
| //selection
|
149
|
-
| //grid
|
150
|
-
| //submit
|
151
|
-
}).each do |el|
|
199
|
+
@doc.root.find(@interactive_xpath, @namespaces).each do |el|
|
152
200
|
yield el
|
153
201
|
end
|
202
|
+
# @doc.root.find(%{
|
203
|
+
# //text
|
204
|
+
# | //textline
|
205
|
+
# | //textbox
|
206
|
+
# | //editbox
|
207
|
+
# | //asset
|
208
|
+
# | //password
|
209
|
+
# | //selection
|
210
|
+
# | //grid
|
211
|
+
# | //submit
|
212
|
+
# }).each do |el|
|
213
|
+
# yield el
|
214
|
+
# end
|
154
215
|
end
|
155
216
|
|
156
217
|
def el_id(el)
|
157
218
|
own_id = el.attributes['id']
|
158
219
|
return '' if own_id.nil? || own_id == ''
|
159
220
|
|
160
|
-
ancestors = el.find(%{
|
161
|
-
ancestor::option[@id != '']
|
162
|
-
| ancestor::group[@id != '']
|
163
|
-
| ancestor::form[@id != '']
|
164
|
-
| ancestor::container[@id != '']
|
165
|
-
})
|
221
|
+
# ancestors = el.find(%{
|
222
|
+
# ancestor::option[@id != '']
|
223
|
+
# | ancestor::group[@id != '']
|
224
|
+
# | ancestor::form[@id != '']
|
225
|
+
# | ancestor::container[@id != '']
|
226
|
+
# })
|
227
|
+
ancestors = el.find(@structural_xpath, @namespaces)
|
166
228
|
ids = ancestors.collect{|a| a.attributes['id']}.select{|a| !a.nil? }
|
167
229
|
ids << own_id
|
168
230
|
ids.collect{|i| i.to_s}.join('/')
|
169
231
|
end
|
170
232
|
|
171
233
|
def text_node(n,t)
|
172
|
-
e = XML::Node.new(n)
|
234
|
+
e = XML::Node.new(n, nil)
|
235
|
+
e.namespaces.namespace = @fab_ns
|
173
236
|
e << t
|
174
237
|
e
|
175
238
|
end
|