ironnails 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +21 -0
- data/VERSION +1 -0
- data/init.rb +1 -0
- data/ironnails.gemspec +96 -0
- data/lib/iron_nails.rb +1 -0
- data/lib/ironnails/bin/IronNails.Library.dll +0 -0
- data/lib/ironnails/bin/IronRuby.Libraries.Yaml.dll +0 -0
- data/lib/ironnails/bin/IronRuby.Libraries.dll +0 -0
- data/lib/ironnails/bin/IronRuby.dll +0 -0
- data/lib/ironnails/bin/Microsoft.Dynamic.dll +0 -0
- data/lib/ironnails/bin/Microsoft.Scripting.Core.dll +0 -0
- data/lib/ironnails/bin/Microsoft.Scripting.ExtensionAttribute.dll +0 -0
- data/lib/ironnails/bin/Microsoft.Scripting.dll +0 -0
- data/lib/ironnails/config/configuration.rb +141 -0
- data/lib/ironnails/config/initializer.rb +144 -0
- data/lib/ironnails/controller/base.rb +135 -0
- data/lib/ironnails/controller/view_operations.rb +101 -0
- data/lib/ironnails/controller.rb +2 -0
- data/lib/ironnails/core_ext/array.rb +15 -0
- data/lib/ironnails/core_ext/class/attribute_accessors.rb +57 -0
- data/lib/ironnails/core_ext/class.rb +8 -0
- data/lib/ironnails/core_ext/fixnum.rb +22 -0
- data/lib/ironnails/core_ext/hash.rb +32 -0
- data/lib/ironnails/core_ext/kernel.rb +26 -0
- data/lib/ironnails/core_ext/string.rb +58 -0
- data/lib/ironnails/core_ext/symbol.rb +78 -0
- data/lib/ironnails/core_ext/system/net/web_request.rb +110 -0
- data/lib/ironnails/core_ext/system/security/secure_string.rb +18 -0
- data/lib/ironnails/core_ext/system/windows/markup/xaml_reader.rb +6 -0
- data/lib/ironnails/core_ext/system/windows/ui_element.rb +17 -0
- data/lib/ironnails/core_ext/time.rb +28 -0
- data/lib/ironnails/core_ext.rb +12 -0
- data/lib/ironnails/errors.rb +19 -0
- data/lib/ironnails/iron_xml.rb +83 -0
- data/lib/ironnails/logger.rb +4 -0
- data/lib/ironnails/logging/buffered_logger.rb +137 -0
- data/lib/ironnails/logging/class_logger.rb +29 -0
- data/lib/ironnails/models/base.rb +16 -0
- data/lib/ironnails/models/bindable_collection.rb +15 -0
- data/lib/ironnails/models/model_mixin.rb +69 -0
- data/lib/ironnails/models.rb +3 -0
- data/lib/ironnails/nails_engine.rb +398 -0
- data/lib/ironnails/observable.rb +117 -0
- data/lib/ironnails/security/secure_string.rb +61 -0
- data/lib/ironnails/version.rb +11 -0
- data/lib/ironnails/view/collections.rb +117 -0
- data/lib/ironnails/view/commands/add_sub_view_command.rb +33 -0
- data/lib/ironnails/view/commands/behavior_command.rb +29 -0
- data/lib/ironnails/view/commands/command.rb +208 -0
- data/lib/ironnails/view/commands/event_command.rb +32 -0
- data/lib/ironnails/view/commands/timed_command.rb +40 -0
- data/lib/ironnails/view/commands.rb +5 -0
- data/lib/ironnails/view/view.rb +190 -0
- data/lib/ironnails/view/view_model.rb +45 -0
- data/lib/ironnails/view/xaml_proxy.rb +226 -0
- data/lib/ironnails/view.rb +5 -0
- data/lib/ironnails/wpf.rb +113 -0
- data/lib/ironnails/wpf_application.rb +30 -0
- data/lib/ironnails.rb +68 -0
- metadata +133 -0
@@ -0,0 +1,57 @@
|
|
1
|
+
# Taken from the Rails codebase. I can't require any gem atm when I can I will use their implementation.
|
2
|
+
#
|
3
|
+
# Extends the class object with class and instance accessors for class attributes,
|
4
|
+
# just like the native attr* accessors for instance attributes.
|
5
|
+
#
|
6
|
+
# class Person
|
7
|
+
# cattr_accessor :hair_colors
|
8
|
+
# end
|
9
|
+
#
|
10
|
+
# Person.hair_colors = [:brown, :black, :blonde, :red]
|
11
|
+
class Class
|
12
|
+
|
13
|
+
def cattr_reader(*syms)
|
14
|
+
syms.flatten.each do |sym|
|
15
|
+
next if sym.is_a?(Hash)
|
16
|
+
class_eval(<<-EOS, __FILE__, __LINE__)
|
17
|
+
unless defined? @@#{sym}
|
18
|
+
@@#{sym} = nil
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.#{sym}
|
22
|
+
@@#{sym}
|
23
|
+
end
|
24
|
+
|
25
|
+
def #{sym}
|
26
|
+
@@#{sym}
|
27
|
+
end
|
28
|
+
EOS
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def cattr_writer(*syms)
|
33
|
+
options = syms.extract_options!
|
34
|
+
syms.flatten.each do |sym|
|
35
|
+
class_eval(<<-EOS, __FILE__, __LINE__)
|
36
|
+
unless defined? @@#{sym}
|
37
|
+
@@#{sym} = nil
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.#{sym}=(obj)
|
41
|
+
@@#{sym} = obj
|
42
|
+
end
|
43
|
+
|
44
|
+
#{"
|
45
|
+
def #{sym}=(obj)
|
46
|
+
@@#{sym} = obj
|
47
|
+
end
|
48
|
+
" unless options[:instance_writer] == false }
|
49
|
+
EOS
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def cattr_accessor(*syms)
|
54
|
+
cattr_reader(*syms)
|
55
|
+
cattr_writer(*syms)
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class Fixnum
|
2
|
+
|
3
|
+
def to_timespan(as=:seconds)
|
4
|
+
case as
|
5
|
+
when :hours || :hour
|
6
|
+
TimeSpan.new(self, 0, 0)
|
7
|
+
when :minutes || :minute
|
8
|
+
TimeSpan.new(0, self, 0)
|
9
|
+
else
|
10
|
+
TimeSpan.new(0, 0, self)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def minutes
|
15
|
+
self * 60
|
16
|
+
end
|
17
|
+
|
18
|
+
def seconds
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class Hash
|
2
|
+
|
3
|
+
#returns a string of post parameters for http posts, url-encoded
|
4
|
+
def to_post_parameters
|
5
|
+
params = ""
|
6
|
+
|
7
|
+
self.each do |k, v|
|
8
|
+
params += "&" unless params.empty?
|
9
|
+
params += "#{k}=#{HttpUtility.url_encode(v.to_s.to_clr_string)}"
|
10
|
+
end
|
11
|
+
|
12
|
+
params
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_s
|
16
|
+
res = self.collect do |k, v|
|
17
|
+
val = case
|
18
|
+
when v.is_a?(String)
|
19
|
+
"\"#{v}\""
|
20
|
+
when v.is_a?(Symbol)
|
21
|
+
":#{v}"
|
22
|
+
else
|
23
|
+
"#{v}"
|
24
|
+
end
|
25
|
+
"#{k.is_a?(Symbol) ? ":#{k}" : "#{k}" } => #{val}"
|
26
|
+
end
|
27
|
+
"{ #{res.join(', ')} }"
|
28
|
+
end
|
29
|
+
|
30
|
+
alias_method :to_str, :to_s
|
31
|
+
alias_method :inspect, :to_s
|
32
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Kernel
|
2
|
+
|
3
|
+
# Sets $VERBOSE to nil for the duration of the block and back to its original value afterwards.
|
4
|
+
#
|
5
|
+
# silence_warnings do
|
6
|
+
# value = noisy_call # no warning voiced
|
7
|
+
# end
|
8
|
+
#
|
9
|
+
# noisy_call # warning voiced
|
10
|
+
def silence_warnings
|
11
|
+
old_verbose, $VERBOSE = $VERBOSE, nil
|
12
|
+
yield
|
13
|
+
ensure
|
14
|
+
$VERBOSE = old_verbose
|
15
|
+
end
|
16
|
+
|
17
|
+
def using(o=nil)
|
18
|
+
begin
|
19
|
+
yield if block_given?
|
20
|
+
ensure
|
21
|
+
o.dispose
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
class String
|
2
|
+
|
3
|
+
# ensures that our url starts with at least http
|
4
|
+
def ensure_http
|
5
|
+
return "http://#{self}" unless /^(ht|f)tp:\/\/.*/i.match(self)
|
6
|
+
self
|
7
|
+
end
|
8
|
+
|
9
|
+
# returns whether this string is a well formed url
|
10
|
+
def is_url?
|
11
|
+
!!(Uri.is_well_formed_uri_string(self.to_clr_string, UriKind.Absolute) && /^(ht|f)tp/i.match(Uri.new(self).scheme))
|
12
|
+
end
|
13
|
+
|
14
|
+
def strip_html
|
15
|
+
self.gsub(/<(.|\n)*?>/, '')
|
16
|
+
end
|
17
|
+
|
18
|
+
def camelize(first_letter_in_uppercase = true)
|
19
|
+
if first_letter_in_uppercase
|
20
|
+
self.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
|
21
|
+
else
|
22
|
+
self[0...1].downcase + camelize(self)[1..-1]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def underscore
|
27
|
+
self.gsub(/::/, '/').
|
28
|
+
gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
|
29
|
+
gsub(/([a-z\d])([A-Z])/, '\1_\2').
|
30
|
+
tr("-", "_").
|
31
|
+
downcase
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_clr_char
|
35
|
+
self.to_clr_string.to_char_array[0]
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_secure_string
|
39
|
+
IronNails::Security::SecureString.secure_string self
|
40
|
+
end
|
41
|
+
|
42
|
+
def decrypt
|
43
|
+
IronNails::Security::SecureString.decrypt_string self
|
44
|
+
end
|
45
|
+
|
46
|
+
def classify
|
47
|
+
Kernel.const_get(self.camelize)
|
48
|
+
end
|
49
|
+
|
50
|
+
def truncate(max=140)
|
51
|
+
if self.size > max
|
52
|
+
s = self[0...max-5]
|
53
|
+
return s.split(' ')[0...s.split(' ').size - 1].join(' ')
|
54
|
+
end
|
55
|
+
self
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
class Symbol
|
2
|
+
|
3
|
+
def to_brush
|
4
|
+
case self
|
5
|
+
when :black
|
6
|
+
Brushes.black
|
7
|
+
when :white
|
8
|
+
Brushes.white
|
9
|
+
when :green
|
10
|
+
Brushes.green
|
11
|
+
when :alice_blue
|
12
|
+
Brushes.alice_blue
|
13
|
+
when :red
|
14
|
+
Brushes.red
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_orientation
|
19
|
+
case self
|
20
|
+
when :horizontal
|
21
|
+
Orientation.horizontal
|
22
|
+
when :vertical
|
23
|
+
Orientation.vertical
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_visibility
|
28
|
+
case self
|
29
|
+
when :visible
|
30
|
+
Visibility.visible
|
31
|
+
when :hidden
|
32
|
+
Visibility.hidden
|
33
|
+
when :collapsed
|
34
|
+
Visibility.collapsed
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_vertical_alignment
|
39
|
+
case self
|
40
|
+
when :center
|
41
|
+
VerticalAlignment.center
|
42
|
+
when :top
|
43
|
+
VerticalAlignment.top
|
44
|
+
when :bottom
|
45
|
+
VerticalAlignment.bottom
|
46
|
+
when :stretch
|
47
|
+
VerticalAlignment.strecht
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def to_horizontal_alignment
|
52
|
+
case self
|
53
|
+
when :center
|
54
|
+
HorizontalAlignment.center
|
55
|
+
when :left
|
56
|
+
HorizontalAlignment.left
|
57
|
+
when :right
|
58
|
+
HorizontalAlignment.right
|
59
|
+
when :stretch
|
60
|
+
HorizontalAlignment.stretch
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def to_binding_mode
|
65
|
+
case self
|
66
|
+
when :default
|
67
|
+
BindingMode.default
|
68
|
+
when :one_time
|
69
|
+
BindingMode.one_time
|
70
|
+
when :one_way
|
71
|
+
BindingMode.one_way
|
72
|
+
when :one_way_to_source
|
73
|
+
BindingMode.one_way_to_source
|
74
|
+
when :two_way
|
75
|
+
BindingMode.two_way
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
class System::Net::WebRequest
|
2
|
+
|
3
|
+
include IronNails::Logging::ClassLogger
|
4
|
+
|
5
|
+
def prepare_for_post(parameters = {})
|
6
|
+
|
7
|
+
params = parameters.to_post_parameters
|
8
|
+
|
9
|
+
self.clr_member(:Method=).call "POST"
|
10
|
+
self.content_type = "application/x-www-form-urlencoded"
|
11
|
+
self.content_length = params.length
|
12
|
+
|
13
|
+
using (stream = StreamWriter.new(self.get_request_stream, System::Text::Encoding.ASCII)) do
|
14
|
+
stream.write params
|
15
|
+
end
|
16
|
+
|
17
|
+
params
|
18
|
+
end
|
19
|
+
|
20
|
+
def prepare_for_async_post(parameters = {}, &callback)
|
21
|
+
self.clr_member(:Method=).call "POST"
|
22
|
+
self.content_type = "application/x-www-form-urlencoded"
|
23
|
+
self.content_length = parameters.to_post_parameters.length
|
24
|
+
|
25
|
+
self.begin_get_request_stream(AsyncCallback.new {|ar| callback.call(ar) }, nil)
|
26
|
+
end
|
27
|
+
|
28
|
+
def perform_post( params, parse_response=nil)
|
29
|
+
logger.debug("IronNails: WebRequest: Performing POST to #{request_uri.to_string}")
|
30
|
+
self.prepare_for_post(params)
|
31
|
+
begin
|
32
|
+
res = self.get_response # we get a real HttpWebResponse back instead of the WebResponse for the C# and VB.NET users. yay for duck typing
|
33
|
+
unless parse_response.nil?
|
34
|
+
using(rdr = StreamReader.new(res.get_response_stream)) do
|
35
|
+
return parse_response.call(rdr)
|
36
|
+
end
|
37
|
+
else
|
38
|
+
return res.status_code == HttpStatusCode.OK
|
39
|
+
end
|
40
|
+
rescue WebException => e
|
41
|
+
handle_exception e
|
42
|
+
end
|
43
|
+
false
|
44
|
+
end
|
45
|
+
|
46
|
+
def perform_async_post( params, parse_response=nil, &callback)
|
47
|
+
logger.debug("IronNails: WebRequest: Performing asynchronous POST to #{request_uri.to_string}")
|
48
|
+
self.prepare_for_async_post params do |async_result|
|
49
|
+
using(post_stream = self.end_get_request_stream(async_result)) do
|
50
|
+
pars = parameters.to_post_parameters
|
51
|
+
post_stream.write pars.convert_to_bytes, 0, pars.size
|
52
|
+
end
|
53
|
+
|
54
|
+
self.begin_get_response(AsyncCallback.new { |response|
|
55
|
+
res = self.end_get_response response
|
56
|
+
using(rdr = StreamReader.new(res.get_response_stream)) do
|
57
|
+
parse_response.call(rdr)
|
58
|
+
end unless parse_response.nil?
|
59
|
+
callback.call res.status_code == HttpStatusCode.OK if block_given?
|
60
|
+
}, nil);
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
def perform_get( parse_response=nil)
|
66
|
+
logger.debug("IronNails: WebRequest: Performing GET to #{request_uri.to_string}")
|
67
|
+
begin
|
68
|
+
response = self.get_response
|
69
|
+
using(rdr = StreamReader.new(response.get_response_stream)) do
|
70
|
+
parse_response.call(rdr)
|
71
|
+
end unless parse_response.nil?
|
72
|
+
rescue WebException => e
|
73
|
+
handle_exception e
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def perform_async_get( parse_response=nil, &callback)
|
78
|
+
logger.debug("IronNails: WebRequest: Performing asynchronous GET to #{request_uri.to_string}")
|
79
|
+
self.begin_get_response AsyncCallback.new{ |response|
|
80
|
+
begin
|
81
|
+
res = self.end_get_response(response)
|
82
|
+
using(rdr = StreamReader.new(res.get_response_stream)) do
|
83
|
+
obj = parse_response.call(rdr)
|
84
|
+
callback.call(obj) if block_given?
|
85
|
+
end if parse_response
|
86
|
+
rescue WebException => e
|
87
|
+
handle_exception e
|
88
|
+
end
|
89
|
+
}, nil
|
90
|
+
end
|
91
|
+
|
92
|
+
def handle_exception(e)
|
93
|
+
logger.error("ERROR: IronNails: WebRequest (#{request_uri.to_string}):\nThere was an error while executing the web request: #{e.message}")
|
94
|
+
status = e.status;
|
95
|
+
if status == WebExceptionStatus.protocol_error
|
96
|
+
httpResponse = e.response
|
97
|
+
|
98
|
+
case httpResponse.status_code
|
99
|
+
when HttpStatusCode.NotModified: # 304 Not modified = no new tweets so ignore error.
|
100
|
+
break;
|
101
|
+
when HttpStatusCode.Unauthorized: # unauthorized
|
102
|
+
raise SecurityException.new("Not Authorized.");
|
103
|
+
else
|
104
|
+
raise
|
105
|
+
end
|
106
|
+
else
|
107
|
+
raise
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module System
|
2
|
+
|
3
|
+
module Security
|
4
|
+
|
5
|
+
class SecureString
|
6
|
+
|
7
|
+
def to_insecure_string
|
8
|
+
IronNails::Security::SecureString.unsecure_string self
|
9
|
+
end
|
10
|
+
|
11
|
+
def encrypt
|
12
|
+
IronNails::Security::SecureString.encrypt_string self
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module System
|
2
|
+
|
3
|
+
module Windows
|
4
|
+
|
5
|
+
class UIElement
|
6
|
+
|
7
|
+
@@empty_delegate = System::Action.new { }
|
8
|
+
@@empty_priorty = System::Windows::Threading::DispatcherPriority.render
|
9
|
+
|
10
|
+
def refresh
|
11
|
+
self.dispatcher.invoke @@empty_priorty, @@empty_delegate
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'time'
|
2
|
+
class Time
|
3
|
+
|
4
|
+
def humanize
|
5
|
+
humanized_time = ""
|
6
|
+
delta = Time.now - self
|
7
|
+
case
|
8
|
+
when delta <= 1
|
9
|
+
humanized_time = "just now"
|
10
|
+
when delta < 60
|
11
|
+
humanized_time = "#{delta.floor} seconds ago"
|
12
|
+
when delta < 120
|
13
|
+
humanized_time = "about a minute ago"
|
14
|
+
when delta < (45 * 60)
|
15
|
+
humanized_time = "#{(delta / 60).round} minutes ago"
|
16
|
+
when delta < (90 * 60)
|
17
|
+
humanized_time = "about an hour ago"
|
18
|
+
when delta < (86400)
|
19
|
+
humanized_time = "about #{(delta / 3600 ).round } hours ago"
|
20
|
+
when delta < (48 * 3600)
|
21
|
+
humanized_time = "1 day ago"
|
22
|
+
else
|
23
|
+
humanized_time = "#{(delta / 86400).round} days ago"
|
24
|
+
end
|
25
|
+
|
26
|
+
humanized_time
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'ironnails/core_ext/array'
|
2
|
+
require 'ironnails/core_ext/class'
|
3
|
+
require 'ironnails/core_ext/fixnum'
|
4
|
+
require 'ironnails/core_ext/hash'
|
5
|
+
require 'ironnails/core_ext/kernel'
|
6
|
+
require 'ironnails/core_ext/string'
|
7
|
+
require 'ironnails/core_ext/symbol'
|
8
|
+
require 'ironnails/core_ext/time'
|
9
|
+
require 'ironnails/core_ext/system/net/web_request'
|
10
|
+
require 'ironnails/core_ext/system/windows/markup/xaml_reader'
|
11
|
+
require 'ironnails/core_ext/system/windows/ui_element'
|
12
|
+
require 'ironnails/core_ext/system/security/secure_string'
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module IronNails
|
2
|
+
|
3
|
+
module Errors
|
4
|
+
|
5
|
+
class IronNailsError < StandardError
|
6
|
+
|
7
|
+
|
8
|
+
end
|
9
|
+
|
10
|
+
class ContractError < IronNails::Errors::IronNailsError
|
11
|
+
|
12
|
+
def initialize(method)
|
13
|
+
super "#{method} needs to be overridden in an implementing class"
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module IronNails
|
2
|
+
|
3
|
+
module Core
|
4
|
+
|
5
|
+
class IronXml
|
6
|
+
|
7
|
+
attr_reader :xml_node, :parent
|
8
|
+
|
9
|
+
def initialize(xml_doc, parent=nil)
|
10
|
+
@xml_node = xml_doc
|
11
|
+
@parent = parent
|
12
|
+
end
|
13
|
+
|
14
|
+
# selects multiple child nodes from the tree
|
15
|
+
def elements(name, &b)
|
16
|
+
if has_element? name
|
17
|
+
ele = @xml_node.select_nodes xp_pref(name)
|
18
|
+
ele.each do |el|
|
19
|
+
raise "Expected a block for multiple elements" unless block_given?
|
20
|
+
b.call IronXml.new(el, self) unless el.nil?
|
21
|
+
end
|
22
|
+
else
|
23
|
+
[]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# selects a single child node from the tree
|
28
|
+
def element(name)
|
29
|
+
if has_element? name
|
30
|
+
ele = @xml_node.select_single_node xp_pref(name)
|
31
|
+
xml = IronXml.new(ele, self)
|
32
|
+
yield xml if block_given?
|
33
|
+
xml
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# indicates whether the element is present in the selected nodes.
|
38
|
+
def has_element?(name)
|
39
|
+
!@xml_node.nil? && @xml_node.select_nodes("#{name}").count > 0
|
40
|
+
end
|
41
|
+
|
42
|
+
# the XPath prefix (rooted or not?)
|
43
|
+
def xp_pref(name)
|
44
|
+
@parent.nil? ? "//#{name}" : name
|
45
|
+
end
|
46
|
+
|
47
|
+
# the value of the selected node
|
48
|
+
def value
|
49
|
+
@xml_node.inner_text
|
50
|
+
end
|
51
|
+
|
52
|
+
# parses an xml document. +content+ can be either
|
53
|
+
# a string containing xml, a path to an xml document
|
54
|
+
# or a System::IO::Reader. You tell IronXml which type of
|
55
|
+
# content you have by passing in a +content_type+.
|
56
|
+
# +content_type+ is a symbol that defaults to :string
|
57
|
+
# it expects a block to traverse the xml provided.
|
58
|
+
def self.parse(content, content_type = :string, &b)
|
59
|
+
xdoc = XmlDocument.new
|
60
|
+
|
61
|
+
if content_type == :string
|
62
|
+
xdoc.load_xml(content)
|
63
|
+
else
|
64
|
+
xdoc.load(content)
|
65
|
+
end
|
66
|
+
b.call(IronXml.new(xdoc))
|
67
|
+
end
|
68
|
+
|
69
|
+
def method_missing(sym, *args, &b)
|
70
|
+
# this is what gives us the syntactic sugar over the
|
71
|
+
# Xlinq like syntax
|
72
|
+
if block_given?
|
73
|
+
self.elements(sym.to_s, &b)
|
74
|
+
else
|
75
|
+
self.element(sym.to_s).value
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|