Class: REXML::Element

Inherits:
Object
  • Object
show all
Defined in:
lib/atom/xml.rb

Instance Method Summary collapse

Instance Method Details

#copy_extensions(coll) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/atom/xml.rb', line 31

def copy_extensions(coll)
  # XXX also look for attributes
  children.find_all do |child| 
    child.respond_to? :namespace and child.namespace != Atom::NS 
  end.each do |elem|
    e = elem.dup

    # because namespaces might be defined on parents
    unless e.prefix.empty?
      e.add_namespace e.prefix, e.namespace
    end

    coll << e
  end
end

#each_atom_element(name) ⇒ Object



25
26
27
28
29
# File 'lib/atom/xml.rb', line 25

def each_atom_element name
  XPath.each(self, "./atom:#{name}", { "atom" => Atom::NS }) do |elem|
    yield elem
  end
end

#fill_attr_element(top, array, kind) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/atom/xml.rb', line 112

def fill_attr_element(top, array, kind)
  each_atom_element(kind) do |elem|
    thing = array.new

    thing.class.attrs.each do |name,req|
      value = elem.ns_attr name.to_s
      if value and name == :href
        begin
          thing[name.to_s] = (top.base.to_uri + value).to_s
        rescue URI::BadURIError
          raise "Document contains relative URIs and no xml:base. You must pass a base URI to #parse()"
        end
      elsif value
        thing[name.to_s] = value
      end
    end
  end
end

#fill_elem_element(top, kind) ⇒ Object



102
103
104
105
106
107
108
109
110
# File 'lib/atom/xml.rb', line 102

def fill_elem_element(top, kind)
  each_atom_element(kind) do |elem|
    person = top.send("#{kind}s".to_sym).new

    ["name", "uri", "email"].each do |name|
      person.send("#{name}=".to_sym, elem.get_atom_text(name))
    end
  end
end

#fill_text_construct(entry, name) ⇒ Object



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
# File 'lib/atom/xml.rb', line 69

def fill_text_construct(entry, name)
  text = get_atom_element(name)
  if text
    type = text.ns_attr("type")
    src = text.ns_attr("src")

    if src and name == :content
      # the only content is out of line
      entry.send( "#{name}=".to_sym, "")
      entry.send(name.to_sym)["src"] = src
    elsif type == "xhtml"
      div = XPath.first(text, "./xhtml:div", { "xhtml" => XHTML::NS })
      unless div
        raise "Refusing to parse type='xhtml' with no <div/> wrapper"
      end

      # content is the serialized content of the <div> wrapper
      entry.send( "#{name}=".to_sym, div )
    else
      raw = text.text || ""
      entry.send( "#{name}=", raw )
    end

    if text.attributes["xml:base"]
      entry.send(name.to_sym).base = text.attributes["xml:base"]
    end

    if type and type != "text"
      entry.send(name.to_sym)["type"] = type
    end
  end
end

#get_atom_element(name) ⇒ Object



21
22
23
# File 'lib/atom/xml.rb', line 21

def get_atom_element name
  XPath.first(self, "./atom:#{name}", { "atom" => Atom::NS })
end

#get_atom_text(name) ⇒ Object

get the text content of a descendant element in the Atom namespace



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

def get_atom_text name
  elem = get_atom_element name
  if elem
    elem.text
  else
    nil
  end
end

#ns_attr(name) ⇒ Object

a workaround for the odd way in which REXML handles namespaces returns the value of the attribute name that’s in the same namespace as this element



59
60
61
62
63
64
65
66
67
# File 'lib/atom/xml.rb', line 59

def ns_attr name
  if not self.prefix.empty?
    attr = self.prefix + ":" + name
  else
    attr = name
  end

  self.attributes[attr]
end

#to_atom_entry(base = "") ⇒ Object

‘base’ is the URI that you fetched this document from.



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/atom/xml.rb', line 132

def to_atom_entry base = ""
  unless self.name == "entry" and self.namespace == Atom::NS
    raise TypeError, "this isn't an atom:entry! (name: #{self.name}, ns: #{self.namespace})"
  end

  entry = Atom::Entry.new

  entry.base = if attributes["xml:base"]
    (URI.parse(base) + attributes["xml:base"]).to_s
  else
    # go with the URL we were passed in
    base
  end

  # Text constructs
  entry.class.elements.find_all { |n,k,r| k.ancestors.member? Atom::Text }.each do |n,k,r|
    fill_text_construct(entry, n)
  end

  ["id", "published", "updated"].each do |name|
    entry.send("#{name}=".to_sym, get_atom_text(name))
  end

  ["author", "contributor"].each do |type|
    fill_elem_element(entry, type)
  end

  {"link" => entry.links, "category" => entry.categories}.each do |k,v|
    fill_attr_element(entry, v, k)
  end
  
  copy_extensions(entry.extensions)

  entry
end

#to_atom_feed(base = "") ⇒ Object

‘base’ is the URI that you fetched this document from.



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/atom/xml.rb', line 169

def to_atom_feed base = ""
  unless self.name == "feed" and self.namespace == Atom::NS
    raise TypeError, "this isn't an atom:feed! (name: #{self.name}, ns: #{self.namespace})"
  end

  feed = Atom::Feed.new
  
  feed.base = if attributes["xml:base"]
    (URI.parse(base) + attributes["xml:base"]).to_s
  else
    # go with the URL we were passed in
    base
  end
  
  # Text constructs
  feed.class.elements.find_all { |n,k,r| k.ancestors.member? Atom::Text }.each do |n,k,r|
    fill_text_construct(feed, n)
  end

  ["id", "updated", "generator", "icon", "logo"].each do |name|
    feed.send("#{name}=".to_sym, get_atom_text(name))
  end

  ["author", "contributor"].each do |type|
    fill_elem_element(feed, type)
  end

  {"link" => feed.links, "category" => feed.categories}.each do |k,v|
    fill_attr_element(feed, v, k)
  end
 
  each_atom_element("entry") do |elem|
    feed << elem.to_atom_entry(feed.base)
  end

  copy_extensions(feed.extensions)

  feed
end