Class: XmlNode

Inherits:
Object
  • Object
show all
Defined in:
lib/xmlutils/xml_doc.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(option = {}) ⇒ XmlNode

Returns a new instance of XmlNode.



49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/xmlutils/xml_doc.rb', line 49

def initialize(option = {})
  args = {parent: nil, attributes: {}, elements: [], prev: [], next: []}.merge(option)
  @name = args[:name] || "OID:#{self.object_id}"
  @attributes = args[:attributes]
  @parent, @elements, @prev, @next = args[:parent], args[:elements], args[:prev], args[:next]
  
  if @parent
    @prev << @parent unless @prev.include?(@parent)
    @parent.elements << self unless @parent.elements.include?(self)
    @parent.next << self unless @parent.next.include?(self)
  end
end

Instance Attribute Details

#attributesObject

Returns the value of attribute attributes.



47
48
49
# File 'lib/xmlutils/xml_doc.rb', line 47

def attributes
  @attributes
end

#elementsObject

Returns the value of attribute elements.



47
48
49
# File 'lib/xmlutils/xml_doc.rb', line 47

def elements
  @elements
end

#nameObject

Returns the value of attribute name.



47
48
49
# File 'lib/xmlutils/xml_doc.rb', line 47

def name
  @name
end

#nextObject

Returns the value of attribute next.



47
48
49
# File 'lib/xmlutils/xml_doc.rb', line 47

def next
  @next
end

#parentObject

Returns the value of attribute parent.



47
48
49
# File 'lib/xmlutils/xml_doc.rb', line 47

def parent
  @parent
end

#prevObject

Returns the value of attribute prev.



47
48
49
# File 'lib/xmlutils/xml_doc.rb', line 47

def prev
  @prev
end

Class Method Details

.copy(node) ⇒ Object



225
226
227
228
229
230
231
# File 'lib/xmlutils/xml_doc.rb', line 225

def self.copy node
  duplicate = XmlNode.new(name: node.name, parent: nil, attributes: node.attributes.dup)
  node.elements.map{|subnode|self.copy(subnode)}.each do|subnode|
    duplicate.add_element subnode
  end
  return duplicate
end

.escape_xml(text) ⇒ Object



139
140
141
142
143
# File 'lib/xmlutils/xml_doc.rb', line 139

def self.escape_xml(text)
  text.gsub('&', '&amp;')
      .gsub('<', '&lt;')
      .gsub('>', '&gt;')
end

.escape_xml_attr(text) ⇒ Object



145
146
147
148
149
150
151
# File 'lib/xmlutils/xml_doc.rb', line 145

def self.escape_xml_attr(text)
  text.gsub('&', '&amp;')
      .gsub('<', '&lt;')
      .gsub('>', '&gt;')
      .gsub('"', '&quot;')
      .gsub("'", '&apos;')
end

.make_str_from(xml) ⇒ Object



153
154
155
156
157
158
159
# File 'lib/xmlutils/xml_doc.rb', line 153

def self.make_str_from xml
  text = xml.dup
  [['&lt;','<'], ['&gt;','>'], ['&amp;','&'], ['&apos;',"'"], ['&quot;','"']].each do |xstr, str|
    text.gsub!(xstr, str)
  end
  text
end

.make_xml_from(string) ⇒ Object



161
162
163
164
165
166
167
# File 'lib/xmlutils/xml_doc.rb', line 161

def self.make_xml_from string
  string.gsub('&', '&amp;')
        .gsub('<', '&lt;')
        .gsub('>', '&gt;')
        .gsub("'", '&apos;')
        .gsub('"', '&quot;')
end

Instance Method Details

#add_attributes(hash) ⇒ Object

attributes operation #



173
174
175
176
177
# File 'lib/xmlutils/xml_doc.rb', line 173

def add_attributes hash
  (@attributes[:text] ||= []) << hash[:text] if hash[:text]
  hash.delete(:text)
  @attributes.merge!(hash)
end

#add_content(content) ⇒ Object

content operation #



191
192
193
# File 'lib/xmlutils/xml_doc.rb', line 191

def add_content content
  @elements << content
end

#add_element(elem) ⇒ Object



205
206
207
208
209
210
211
212
# File 'lib/xmlutils/xml_doc.rb', line 205

def add_element elem
  if elem.is_a?(XmlNode)
    @elements << elem unless @elements.include?(elem)
    @next << elem unless @next.include?(elem)
    elem.parent = self
    elem.prev << self unless elem.prev.include?(self)
  end
end

#delete_attribute(key) ⇒ Object



183
184
185
# File 'lib/xmlutils/xml_doc.rb', line 183

def delete_attribute key
  @attributes.delete(key) unless key==:text
end

#delete_contentObject



201
202
203
# File 'lib/xmlutils/xml_doc.rb', line 201

def delete_content
  @elements = @elements.find_all{|c|!c.instance_of?(XmlNode)}
end

#delete_elements(&block) ⇒ Object



218
219
220
221
222
223
# File 'lib/xmlutils/xml_doc.rb', line 218

def delete_elements &block
  return [] unless block
  elems = search_elements(&block)
  elems.each{|elem|@elements.delete(elem)}
  return elems
end

#modify_attributes(hash) ⇒ Object



179
180
181
# File 'lib/xmlutils/xml_doc.rb', line 179

def modify_attributes hash
  add_attributes hash
end

#modify_content(content) ⇒ Object



195
196
197
198
199
# File 'lib/xmlutils/xml_doc.rb', line 195

def modify_content content
  @attributes[:text] = []
  @elements.delete_if{|e|e.is_a?(XmlNode)}
  @elements << content
end

#pretty(format, method, indent = 2) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/xmlutils/xml_doc.rb', line 126

def pretty format, method, indent=2
  case method
  when :xml
    pretty_xml = ""
    XmlUtils::Formatters::Default.new.write(XmlUtils.parse(self.send(format)), pretty_xml)
    return pretty_xml
  when :json
    return JSON.pretty_generate(self.send(format))
  else
    raise ArgumentError, "Unknown pretty method: #{method.inspect}"
  end
end

#search_elements(&block) ⇒ Object



214
215
216
# File 'lib/xmlutils/xml_doc.rb', line 214

def search_elements &block
  return ( block ? @elements.find_all(&block) : [] )
end

#to_docObject

文档化 ([attributes, {name: […]]})



82
83
84
85
86
87
88
# File 'lib/xmlutils/xml_doc.rb', line 82

def to_doc
  doc = {}
  doc[@name] = []
  doc[@name] << @attributes
  @elements.each{|e|doc[@name] << e.to_doc}
  return doc
end

#to_objObject

对象化 (like js: {‘-attr’: val, ‘#text’: text, obj: {…}})



91
92
93
94
95
96
97
98
99
100
101
# File 'lib/xmlutils/xml_doc.rb', line 91

def to_obj
  doc = {}
  @attributes.each do|k,v|
    h = k==:text ? '#' : '-'
    doc["#{h}#{k}"] = v
  end
  @elements.each do|elem|
    doc.merge! elem.to_obj
  end
  return {@name => doc}
end

#to_triadObject Also known as: to_a

三元组 ([name, attributes, [name, attributes, …]])



67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/xmlutils/xml_doc.rb', line 67

def to_triad
  attrs,elems = {},[]
  @attributes.each do|k,v|
    unless k == :text
      attrs[k] = v
    else
      elems += [v].flatten
    end
  end
  elems += @elements.map{|c|c.to_triad}
  [@name, attrs, elems]
end

#to_xmlObject

XML(手动序列化,需确保属性/文本已转义)



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/xmlutils/xml_doc.rb', line 104

def to_xml
  attrs, content = '', ''
  @attributes.each do |k,v|
    if k == :text
      content += XmlNode.escape_xml([v].flatten.join("\n"))
    elsif k == :namespace && !v
      next
    else
      attrs += " #{k}=\"#{XmlNode.escape_xml_attr(v.to_s)}\""
    end
  end
  return "<#{@name}#{attrs}/>" if @elements.size==0 && !@attributes[:text]
  @elements.each do|e|
    content += if e.is_a?(XmlNode)
      e.to_xml
    elsif e.instance_of?(String)
      XmlNode.escape_xml(e)
    end
  end
  return "<#{@name}#{attrs}>#{content}</#{@name}>"
end