Class: XmlFu::Node

Inherits:
Object
  • Object
show all
Defined in:
lib/xml-fu/node.rb

Overview

Class to contain logic for converting a key/value pair into an XML node

Defined Under Namespace

Classes: InvalidAttributesException

Constant Summary

XS_DATETIME_FORMAT =

xs:dateTime format.

"%Y-%m-%dT%H:%M:%SZ"
ALGORITHMS =

default set of algorithms to choose from

{
  :lower_camelcase => lambda { |sym| sym.to_s.lower_camelcase },
  :camelcase => lambda { |sym| sym.to_s.camelcase },
  :snakecase => lambda { |sym| sym.to_s },
  :none => lambda { |sym| sym.to_s }
}

Instance Attribute Summary (collapse)

Class Method Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (Node) initialize(name, value, attributes = {})

Create XmlFu::Node object

Parameters:

  • name (String, Symbol)

    Name of node

  • value

    Simple Value or nil

  • attributes (Hash) (defaults to: {})

    Optional hash of attributes to apply to XML Node



48
49
50
51
52
53
54
55
# File 'lib/xml-fu/node.rb', line 48

def initialize(name, value, attributes={})
  @escape_xml = true
  @self_closing = false
  @content_type = "container"
  self.attributes = attributes
  self.value = value
  self.name = name
end

Instance Attribute Details

- (Object) attributes

initialize



57
58
59
# File 'lib/xml-fu/node.rb', line 57

def attributes
  @attributes
end

- (Object) content_type

Returns the value of attribute content_type



42
43
44
# File 'lib/xml-fu/node.rb', line 42

def content_type
  @content_type
end

- (Object) escape_xml

self.symbol_conversion_algorithm=



40
41
42
# File 'lib/xml-fu/node.rb', line 40

def escape_xml
  @escape_xml
end

- (Object) name

Returns the value of attribute name



66
67
68
# File 'lib/xml-fu/node.rb', line 66

def name
  @name
end

- (Object) self_closing

Returns the value of attribute self_closing



41
42
43
# File 'lib/xml-fu/node.rb', line 41

def self_closing
  @self_closing
end

Class Method Details

+ (lambda) symbol_conversion_algorithm

Class method for retrieving global Symbol-to-string conversion algorithm

Returns:

  • (lambda)


28
29
30
# File 'lib/xml-fu/node.rb', line 28

def self.symbol_conversion_algorithm
  @symbol_conversion_algorithm ||= ALGORITHMS[:lower_camelcase]
end

+ (Object) symbol_conversion_algorithm=(algorithm)

Class method for setting global Symbol-to-string conversion algorithm

Parameters:

  • algorithm (lambda)

    Should accept a symbol as an argument and return a string

Raises:

  • (ArgumentError)


34
35
36
37
38
# File 'lib/xml-fu/node.rb', line 34

def self.symbol_conversion_algorithm=(algorithm)
  algorithm = ALGORITHMS[algorithm] unless algorithm.respond_to?(:call)
  raise(ArgumentError, "Invalid symbol conversion algorithm") unless algorithm
  @symbol_conversion_algorithm = algorithm
end

Instance Method Details

- (Object) name_parse_special_characters(val)

Converts name into proper XML node name

Parameters:

  • val (String, Symbol)

    Raw name



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
# File 'lib/xml-fu/node.rb', line 87

def name_parse_special_characters(val)
  use_this = val.dup

  # Ensure that we don't have special characters at end of name
  while ["!","/","*"].include?(use_this.to_s[-1,1]) do
    # Will this node contain escaped XML?
    if use_this.to_s[-1,1] == '!'
      @escape_xml = false
      use_this.chop!
    end

    # Will this be a self closing node?
    if use_this.to_s[-1,1] == '/'
      @self_closing = true 
      use_this.chop!
    end

    # Will this node contain a collection of sibling nodes?
    if use_this.to_s[-1,1] == '*'
      @content_type = "collection"
      use_this.chop!
    end
  end

  return use_this
end

- (Object) to_xml

Create XML String from XmlFu::Node object



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/xml-fu/node.rb', line 146

def to_xml
  xml = Builder::XmlMarkup.new
  case
  when @self_closing && @content_type == 'container'
    xml.tag!(@name, @attributes)
  when @value.nil? 
    xml.tag!(@name, @attributes.merge!("xsi:nil" => "true"))
  when ::Hash === @value
    xml.tag!(@name, @attributes) { xml << XmlFu::Hash.to_xml(@value) }
  when ::Array === @value
    case @content_type
    when "collection"
      xml << XmlFu::Array.to_xml(@value.flatten, { 
        :key => (@self_closing ? "#{@name}/" : @name),
        :attributes => @attributes,
        :content_type => "collection"
      })
    when "container"
      xml.tag!(@name, @attributes) { xml << XmlFu::Array.to_xml(@value) }
    else
      # Shouldn't be anything else
    end
  else
    xml.tag!(@name, @attributes) { xml << self.value.to_s }
  end
  xml.target!
end

- (String?) value

Value can be nil, else it should return a String value.

Returns:



140
141
142
143
# File 'lib/xml-fu/node.rb', line 140

def value
  return CGI.escapeHTML(@value) if String === @value && @escape_xml
  return @value
end

- (Object) value=(val)

Custom Setter for @value instance method



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/xml-fu/node.rb', line 115

def value=(val)
  case val
  when ::String   then @value = val.to_s
  when ::Hash     then @value = val
  when ::Array    then @value = val
  when ::DateTime then @value = val.strftime XS_DATETIME_FORMAT
  when ::Time     then @value = val.strftime XS_DATETIME_FORMAT
  when ::Date     then @value = val.strftime XS_DATETIME_FORMAT
  else
    if val.respond_to?(:to_datetime)
      @value = val.to_datetime
    elsif val.respond_to?(:call)
      @value = val.call
    elsif val.nil?
      @value = nil
    else
      @value = val.to_s
    end
  end
rescue => e
  @value = val.to_s
end