Skip to content

Commit

Permalink
Added namespace detection for TypeConverter.
Browse files Browse the repository at this point in the history
  • Loading branch information
r10r committed Sep 2, 2013
1 parent c151543 commit 3d076cb
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 11 deletions.
32 changes: 21 additions & 11 deletions lib/nori/type_converter.rb
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
require 'rexml/document'

class Nori
class TypeConverter
module XmlNamespace
XML_SCHEMA = 'http://www.w3.org/2001/XMLSchema'
XML_SCHEMA_INSTANCE = 'http://www.w3.org/2001/XMLSchema-instance'
end

attr_accessor :attribute_namespace, :type_attribute_name, :type_namespace, :conversions
attr_accessor :attribute_prefix, :type_attribute_name, :type_prefix, :conversions

def initialize(conversions = {})
@attribute_namespace = nil
@attribute_prefix = nil
@type_attribute_name = 'type'
@type_namespace = nil
@type_prefix = nil
@conversions = conversions
end

def namespaced_type_attribute
@namespaced_type_attribute ||= @attribute_namespace.nil? ? @type_attribute_name : "#{@attribute_namespace}:#{@type_attribute_name}"
@namespaced_type_attribute ||= @attribute_prefix.nil? ? @type_attribute_name : "#{@attribute_prefix}:#{@type_attribute_name}"
end

def conversion(type)
Expand All @@ -35,13 +32,26 @@ def type(attributes)
end

def type_namespace_matches?(type)
@type_namespace.nil? && type.index(':').nil? || type.index(@type_namespace + ":") == 0
@type_prefix.nil? && type.index(':').nil? || type.index(@type_prefix + ":") == 0
end

def strip_namespace(type)
@type_namespace.nil? ? type : type.gsub(/^#{@type_namespace}:/, '')
@type_prefix.nil? ? type : type.gsub(/^#{@type_prefix}:/, '')
end

def detect_namespace_prefixes!(xml, opts = {})
document = REXML::Document.new(xml)
namespaces = REXML::XPath.first(document.root).namespaces
@attribute_prefix = namespaces.key(opts[:attribute_namespace] || XmlNamespace::XML_SCHEMA_INSTANCE)
@type_prefix = namespaces.key(opts[:type_namespace] || XmlNamespace::XML_SCHEMA)
end

module XmlNamespace
XML_SCHEMA = 'http://www.w3.org/2001/XMLSchema'
XML_SCHEMA_INSTANCE = 'http://www.w3.org/2001/XMLSchema-instance'
end

# -- Type Converter

class NoConvert
def self.convert(value)
Expand Down
58 changes: 58 additions & 0 deletions spec/nori/type_converter_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
require 'spec_helper'

describe Nori::TypeConverter do
describe "#detect_namespace_prefixes!" do
let(:namespaces) { {} }
let(:type_converter) { Nori::TypeConverter.new.tap {|c| c.detect_namespace_prefixes!(xml, namespaces)} }

context 'no namespaces' do
let(:xml) {
<<-EOT
<?xml version="1.0" encoding="UTF-8"?>
<Envelope>
<Body>
</Body>
</Envelope>
EOT
}
subject { type_converter }
its(:attribute_prefix) { should be_nil }
its(:type_prefix) { should be_nil }
end

context 'XMLSchema namespace (default)' do
let(:xml) {
<<-EOT
subject { converter }
<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
<Body>
</Body>
</Envelope>
EOT
}
subject { type_converter }
its(:attribute_prefix) { should eq('xsi') }
its(:type_prefix) { should eq('xsd') }
end

context 'custom namespace' do
let(:namespaces) {
{ :attribute_namespace => 'http://company.com/foo', :type_namespace => 'http://company.com/bar' }
}
let(:xml) {
<<-EOT
subject { converter }
<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns:foo="http://company.com/foo" xmlns:bar="http://company.com/bar" >
<Body>
</Body>
</Envelope>
EOT
}
subject { type_converter }
its(:attribute_prefix) { should eq('foo') }
its(:type_prefix) { should eq('bar') }
end
end
end

0 comments on commit 3d076cb

Please sign in to comment.