-
- def self.from_xml(xml, create=false)
- begin
- p = XML::Parser.string(xml)
- doc = p.parse
-
- cs = Changeset.new
-
- doc.find('//osm/changeset').each do |pt|
- if create
- cs.created_at = Time.now.getutc
- # initial close time is 1h ahead, but will be increased on each
- # modification.
- cs.closed_at = cs.created_at + IDLE_TIMEOUT
- # initially we have no changes in a changeset
- cs.num_changes = 0
- end
-
- pt.find('tag').each do |tag|
- cs.add_tag_keyval(tag['k'], tag['v'])
- end
- end
- rescue Exception => ex
- cs = nil
+
+ def self.from_xml(xml, create: false)
+ p = XML::Parser.string(xml, :options => XML::Parser::Options::NOERROR)
+ doc = p.parse
+ pt = doc.find_first("//osm/changeset")
+
+ if pt
+ Changeset.from_xml_node(pt, :create => create)
+ else
+ raise OSM::APIBadXMLError.new("changeset", xml, "XML doesn't contain an osm/changeset element.")
+ end
+ rescue LibXML::XML::Error, ArgumentError => e
+ raise OSM::APIBadXMLError.new("changeset", xml, e.message)
+ end
+
+ def self.from_xml_node(pt, create: false)
+ cs = Changeset.new
+ if create
+ cs.created_at = Time.now.utc
+ # initial close time is 1h ahead, but will be increased on each
+ # modification.
+ cs.closed_at = cs.created_at + IDLE_TIMEOUT
+ # initially we have no changes in a changeset
+ cs.num_changes = 0
+ end
+
+ pt.find("tag").each do |tag|
+ raise OSM::APIBadXMLError.new("changeset", pt, "tag is missing key") if tag["k"].nil?
+ raise OSM::APIBadXMLError.new("changeset", pt, "tag is missing value") if tag["v"].nil?
+
+ cs.add_tag_keyval(tag["k"], tag["v"])