Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'namespaces'

  • Loading branch information...
commit c4ac573f66a1b822dd00ab4d730ab8d255aa100a 2 parents c3390e7 + c84ed90
@bkeepers bkeepers authored
View
19 lib/happymapper.rb
@@ -66,9 +66,6 @@ def tag_name
end
def parse(xml, options = {})
- # locally scoped copy of namespace for this parse run
- namespace = @namespace
-
if xml.is_a?(XML::Node)
node = xml
else
@@ -81,22 +78,14 @@ def parse(xml, options = {})
root = node.name == tag_name
end
- # This is the entry point into the parsing pipeline, so the default
- # namespace prefix registered here will propagate down
- namespaces = node.namespaces
- if namespaces && namespaces.default
- already_assigned = namespaces.definitions.detect do |defn|
- namespaces.default && namespaces.default.href == defn.href && defn.prefix
- end
- namespaces.default_prefix = DEFAULT_NS unless already_assigned
- namespace ||= DEFAULT_NS
- end
+ namespace = @namespace || (node.namespaces && node.namespaces.default)
+ namespace = "#{DEFAULT_NS}:#{namespace}" if namespace
xpath = root ? '/' : './/'
- xpath += "#{namespace}:" if namespace
+ xpath += "#{DEFAULT_NS}:" if namespace
xpath += tag_name
- nodes = node.find(xpath)
+ nodes = node.find(xpath, Array(namespace))
collection = nodes.collect do |n|
obj = new
View
13 lib/happymapper/item.rb
@@ -59,7 +59,7 @@ def from_xml_node(node, namespace)
def xpath(namespace = self.namespace)
xpath = ''
xpath += './/' if options[:deep]
- xpath += "#{namespace}:" if namespace
+ xpath += "#{DEFAULT_NS}:" if namespace
xpath += tag
# puts "xpath: #{xpath}"
xpath
@@ -129,16 +129,15 @@ def constantize(type)
def find(node, namespace, &block)
# this node has a custom namespace (that is present in the doc)
- if self.namespace && node.namespaces.find_by_prefix(self.namespace)
- # from the class definition
- namespace = self.namespace
- elsif options[:namespace] && node.namespaces.find_by_prefix(options[:namespace])
+ if self.namespace
+ namespace = "#{DEFAULT_NS}:#{self.namespace}"
+ elsif options[:namespace]
# from an element definition
- namespace = options[:namespace]
+ namespace = "#{DEFAULT_NS}:#{options[:namespace]}"
end
if element?
- result = node.find_first(xpath(namespace))
+ result = node.find_first(xpath(namespace), namespace)
# puts "vfxn: #{xpath} #{result.inspect}"
if result
value = yield(result)
View
17 spec/fixtures/nested_namespaces.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<EDXLDistribution>
+ <contentObject>
+ <confidentiality>Sensitive</confidentiality>
+ <xmlContent>
+ <embeddedXMLContent>
+ <ns1:alert xmlns:ns1="http://schemas.google.com/analytics/2009">
+ <severity>Severe</severity>
+ <ns1:identifier>CDC-2006-183</ns1:identifier>
+ <ns1:info>
+ <ns1:category>Health</ns1:category>
+ </ns1:info>
+ </ns1:alert>
+ </embeddedXMLContent>
+ </xmlContent>
+ </contentObject>
+</EDXLDistribution>
View
4 spec/happymapper_item_spec.rb
@@ -65,8 +65,8 @@ class Bar; end
it "should prepend namespace if namespace exists" do
item = HappyMapper::Item.new(:foo, String, :tag => 'foobar')
- item.namespace = 'v2'
- item.xpath.should == 'v2:foobar'
+ item.namespace = 'http://example.com'
+ item.xpath.should == 'happymapper:foobar'
end
end
View
68 spec/happymapper_spec.rb
@@ -7,7 +7,7 @@ class Property
include HappyMapper
tag 'property'
- namespace 'dxp'
+ namespace 'http://schemas.google.com/analytics/2009'
attribute :name, String
attribute :value, String
end
@@ -19,7 +19,7 @@ class Entry
element :id, String
element :updated, DateTime
element :title, String
- element :table_id, String, :namespace => 'dxp', :tag => 'tableId'
+ element :table_id, String, :namespace => 'http://schemas.google.com/analytics/2009', :tag => 'tableId'
has_many :properties, Property
end
@@ -84,7 +84,7 @@ class Address
include HappyMapper
tag 'Address'
- namespace 'v2'
+ namespace 'http://fedex.com/ws/track/v2'
element :city, String, :tag => 'City'
element :state, String, :tag => 'StateOrProvinceCode'
element :zip, String, :tag => 'PostalCode'
@@ -96,7 +96,7 @@ class Event
include HappyMapper
tag 'Events'
- namespace 'v2'
+ namespace 'http://fedex.com/ws/track/v2'
element :timestamp, String, :tag => 'Timestamp'
element :eventtype, String, :tag => 'EventType'
element :eventdescription, String, :tag => 'EventDescription'
@@ -107,7 +107,7 @@ class PackageWeight
include HappyMapper
tag 'PackageWeight'
- namespace 'v2'
+ namespace 'http://fedex.com/ws/track/v2'
element :units, String, :tag => 'Units'
element :value, Integer, :tag => 'Value'
end
@@ -116,7 +116,7 @@ class TrackDetails
include HappyMapper
tag 'TrackDetails'
- namespace 'v2'
+ namespace 'http://fedex.com/ws/track/v2'
element :tracking_number, String, :tag => 'TrackingNumber'
element :status_code, String, :tag => 'StatusCode'
element :status_desc, String, :tag => 'StatusDescription'
@@ -131,7 +131,7 @@ class Notification
include HappyMapper
tag 'Notifications'
- namespace 'v2'
+ namespace 'http://fedex.com/ws/track/v2'
element :severity, String, :tag => 'Severity'
element :source, String, :tag => 'Source'
element :code, Integer, :tag => 'Code'
@@ -143,7 +143,7 @@ class TransactionDetail
include HappyMapper
tag 'TransactionDetail'
- namespace 'v2'
+ namespace 'http://fedex.com/ws/track/v2'
element :cust_tran_id, String, :tag => 'CustomerTransactionId'
end
@@ -151,7 +151,7 @@ class TrackReply
include HappyMapper
tag 'TrackReply'
- namespace 'v2'
+ namespace 'http://fedex.com/ws/track/v2'
element :highest_severity, String, :tag => 'HighestSeverity'
element :more_data, Boolean, :tag => 'MoreData'
has_many :notifications, Notification, :tag => 'Notifications'
@@ -215,7 +215,7 @@ class CurrentWeather
include HappyMapper
tag 'ob'
- namespace 'aws'
+ namespace 'http://www.aws.com/aws'
element :temperature, Integer, :tag => 'temp'
element :feels_like, Integer, :tag => 'feels-like'
element :current_condition, String, :tag => 'current-condition', :attributes => {:icon => String}
@@ -243,7 +243,7 @@ class Item
element :asin, String, :tag => 'ASIN'
element :detail_page_url, URI, :tag => 'DetailPageURL', :parser => :parse
element :manufacturer, String, :tag => 'Manufacturer', :deep => true
- element :point, String, :tag => 'point', :namespace => 'georss'
+ element :point, String, :tag => 'point', :namespace => 'http://www.georss.org/georss'
element :product_group, ProductGroup, :tag => 'ProductGroup', :deep => true, :parser => :new, :raw => true
end
@@ -578,4 +578,50 @@ class Thing
# tree.people.first.modified.should == Time.utc(2008, 1, 3, 16, 41, 31) # 2008-01-03T09:41:31-07:00
# tree.people.first.id.should == 'KWQS-BBQ'
end
+
+ describe 'nested elements with namespaces' do
+ module Namespaces
+ class Info
+ include HappyMapper
+ namespace 'http://schemas.google.com/analytics/2009'
+ element :category, String
+ end
+
+ class Alert
+ include HappyMapper
+ namespace 'http://schemas.google.com/analytics/2009'
+
+ element :identifier, String
+ element :severity, String, :namespace => false
+ has_one :info, Info
+ end
+ class Distribution
+ include HappyMapper
+
+ tag 'EDXLDistribution'
+ has_one :alert, Alert
+ end
+ end
+
+ def mapping
+ @mapping ||= Namespaces::Distribution.parse(fixture_file('nested_namespaces.xml'))
+ end
+
+ it "should parse elements with inline namespace" do
+ lambda { mapping }.should_not raise_error
+ end
+
+ it "should map elements with inline namespace" do
+ mapping.alert.identifier.should == 'CDC-2006-183'
+ end
+
+ it "should map sub elements of with nested namespace" do
+ mapping.alert.info.category.should == 'Health'
+ end
+
+ it "should map elements without a namespace" do
+ mapping.alert.severity.should == 'Severe'
+ end
+ end
+
end
Please sign in to comment.
Something went wrong with that request. Please try again.