ncs_mdes 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +10 -0
- data/.rvmrc +1 -0
- data/.yardopts +5 -0
- data/CHANGELOG.md +18 -0
- data/Gemfile +9 -0
- data/README.md +59 -0
- data/Rakefile +7 -0
- data/bin/mdes-console +21 -0
- data/documents/1.2/Data_Transmission_Schema_V1.2.xsd +13980 -0
- data/documents/2.0/NCS_Transmission_Schema_2.0.01.02.xml +26918 -0
- data/lib/ncs_navigator/mdes/source_documents.rb +103 -0
- data/lib/ncs_navigator/mdes/specification.rb +86 -0
- data/lib/ncs_navigator/mdes/transmission_table.rb +53 -0
- data/lib/ncs_navigator/mdes/variable.rb +119 -0
- data/lib/ncs_navigator/mdes/variable_type.rb +196 -0
- data/lib/ncs_navigator/mdes/version.rb +5 -0
- data/lib/ncs_navigator/mdes.rb +27 -0
- data/ncs_mdes.gemspec +27 -0
- data/spec/ncs_navigator/mdes/source_documents_spec.rb +95 -0
- data/spec/ncs_navigator/mdes/specification_spec.rb +102 -0
- data/spec/ncs_navigator/mdes/transmission_table_spec.rb +89 -0
- data/spec/ncs_navigator/mdes/variable_spec.rb +216 -0
- data/spec/ncs_navigator/mdes/variable_type_spec.rb +202 -0
- data/spec/ncs_navigator/mdes/version_spec.rb +13 -0
- data/spec/ncs_navigator/mdes_spec.rb +9 -0
- data/spec/spec_helper.rb +45 -0
- metadata +165 -0
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'ncs_navigator/mdes'
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
module NcsNavigator::Mdes
|
6
|
+
##
|
7
|
+
# Implements the mechanism for determining where the MDES documents
|
8
|
+
# are stored on a particular system.
|
9
|
+
class SourceDocuments
|
10
|
+
BASE_ENV_VAR = 'NCS_MDES_DOCS_DIR'
|
11
|
+
|
12
|
+
extend Forwardable
|
13
|
+
|
14
|
+
##
|
15
|
+
# The base path for all paths that are not explicitly
|
16
|
+
# configured. It defaults to `'documents'` within this gem and may
|
17
|
+
# be globally overridden by setting `NCS_MDES_DOCS_DIR` in the
|
18
|
+
# runtime environment.
|
19
|
+
#
|
20
|
+
# There's probably no reason to change this in the current version
|
21
|
+
# of the gem.
|
22
|
+
#
|
23
|
+
# @return [String]
|
24
|
+
attr_accessor :base
|
25
|
+
|
26
|
+
##
|
27
|
+
# The MDES version this set of documents describes.
|
28
|
+
#
|
29
|
+
# @return [String]
|
30
|
+
attr_accessor :version
|
31
|
+
|
32
|
+
##
|
33
|
+
# Instance-level alias for {.xmlns}.
|
34
|
+
# @method xmlns
|
35
|
+
# @return [Hash]
|
36
|
+
def_delegator self, :xmlns
|
37
|
+
|
38
|
+
class << self
|
39
|
+
##
|
40
|
+
# Constructs an appropriate instance for the given version.
|
41
|
+
#
|
42
|
+
# @return [SourceDocuments]
|
43
|
+
def get(version)
|
44
|
+
case version
|
45
|
+
when '1.2'
|
46
|
+
create('1.2', '1.2/Data_Transmission_Schema_V1.2.xsd')
|
47
|
+
when '2.0'
|
48
|
+
create('2.0', '2.0/NCS_Transmission_Schema_2.0.01.02.xml')
|
49
|
+
else
|
50
|
+
raise "MDES #{version} is not supported by this version of ncs_mdes"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def create(version, schema)
|
55
|
+
self.new.tap do |sd|
|
56
|
+
sd.version = version
|
57
|
+
sd.schema = schema
|
58
|
+
end
|
59
|
+
end
|
60
|
+
private :create
|
61
|
+
|
62
|
+
##
|
63
|
+
# A mapping of prefixes to XML namespaces for use with
|
64
|
+
# Nokogiri XPath.
|
65
|
+
#
|
66
|
+
# @return [Hash<String, String>]
|
67
|
+
def xmlns
|
68
|
+
{
|
69
|
+
'xs' => 'http://www.w3.org/2001/XMLSchema',
|
70
|
+
'ncs' => 'http://www.nationalchildrensstudy.gov',
|
71
|
+
'ncsdoc' => 'http://www.nationalchildrensstudy.gov/doc'
|
72
|
+
}
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def base
|
77
|
+
@base ||= (
|
78
|
+
ENV[BASE_ENV_VAR] ||
|
79
|
+
File.expand_path(File.join('..', '..', '..', '..', 'documents'), __FILE__)
|
80
|
+
)
|
81
|
+
end
|
82
|
+
|
83
|
+
##
|
84
|
+
# The absolute path to the XML Schema describing the MDES
|
85
|
+
# transmission structure for this instance.
|
86
|
+
#
|
87
|
+
# @return [String]
|
88
|
+
def schema
|
89
|
+
@schema[0, 1] == '/' ? @schema : File.join(base, @schema)
|
90
|
+
end
|
91
|
+
|
92
|
+
##
|
93
|
+
# Set the path to the MDES transmission structure XML Schema.
|
94
|
+
# If the path is relative (i.e., it does not begin with `/`), it
|
95
|
+
# will be interpreted relative to {#base}.
|
96
|
+
#
|
97
|
+
# @param [String] path
|
98
|
+
# @return [String] the provided path
|
99
|
+
def schema=(path)
|
100
|
+
@schema = path
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'ncs_navigator/mdes'
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
require 'logger'
|
5
|
+
require 'nokogiri'
|
6
|
+
|
7
|
+
module NcsNavigator::Mdes
|
8
|
+
class Specification
|
9
|
+
extend Forwardable
|
10
|
+
|
11
|
+
##
|
12
|
+
# @return [SourceDocuments] the source documents this reader is
|
13
|
+
# working from.
|
14
|
+
attr_accessor :source_documents
|
15
|
+
|
16
|
+
##
|
17
|
+
# @method version
|
18
|
+
# @return [String] the version of the MDES to which this instance refers.
|
19
|
+
def_delegator :@source_documents, :version
|
20
|
+
|
21
|
+
##
|
22
|
+
# @param [String,SourceDocuments] version either the string
|
23
|
+
# version of the MDES metadata you would like to read, or a
|
24
|
+
# {SourceDocuments} instance pointing to the appropriate files.
|
25
|
+
# @param [Hash] options
|
26
|
+
# @option options :log a logger to use while reading the specification. If
|
27
|
+
# not specified, a logger pointing to standard error will be used.
|
28
|
+
def initialize(version, options={})
|
29
|
+
@source_documents = case version
|
30
|
+
when SourceDocuments
|
31
|
+
version
|
32
|
+
else
|
33
|
+
SourceDocuments.get(version)
|
34
|
+
end
|
35
|
+
@log = options[:log] || NcsNavigator::Mdes.default_logger
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# @return [Nokogiri::XML::Document] the parsed version of the VDR
|
40
|
+
# XML schema for this version of the MDES.
|
41
|
+
def xsd
|
42
|
+
@xsd ||= Nokogiri::XML(File.read source_documents.schema)
|
43
|
+
end
|
44
|
+
|
45
|
+
##
|
46
|
+
# @return [Array<TransmissionTable>] all the transmission tables
|
47
|
+
# in this version of the MDES.
|
48
|
+
def transmission_tables
|
49
|
+
@transmission_tables ||= read_transmission_tables
|
50
|
+
end
|
51
|
+
|
52
|
+
def read_transmission_tables
|
53
|
+
xsd.xpath(
|
54
|
+
'//xs:element[@name="transmission_tables"]/xs:complexType/xs:sequence/xs:element',
|
55
|
+
source_documents.xmlns
|
56
|
+
).collect { |table_elt|
|
57
|
+
TransmissionTable.from_element(table_elt, :log => @log)
|
58
|
+
}.tap { |tables|
|
59
|
+
tables.each { |t| t.variables.each { |v| v.resolve_type!(types, :log => @log) } }
|
60
|
+
}
|
61
|
+
end
|
62
|
+
private :read_transmission_tables
|
63
|
+
|
64
|
+
##
|
65
|
+
# @return [Array<VariableType>] all the named types in the
|
66
|
+
# MDES. This includes all the code lists.
|
67
|
+
def types
|
68
|
+
@types ||= read_types
|
69
|
+
end
|
70
|
+
|
71
|
+
def read_types
|
72
|
+
xsd.xpath('//xs:simpleType[@name]', source_documents.xmlns).collect do |type_elt|
|
73
|
+
VariableType.from_xsd_simple_type(type_elt, :log => @log)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
private :read_types
|
77
|
+
|
78
|
+
##
|
79
|
+
# A briefer inspection for nicer IRB sessions.
|
80
|
+
#
|
81
|
+
# @return [String]
|
82
|
+
def inspect
|
83
|
+
"#<#{self.class} version=#{version.inspect}>"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'ncs_navigator/mdes'
|
2
|
+
|
3
|
+
module NcsNavigator::Mdes
|
4
|
+
##
|
5
|
+
# One table in the MDES.
|
6
|
+
class TransmissionTable
|
7
|
+
##
|
8
|
+
# Creates a new instance from an `xs:element` describing the table.
|
9
|
+
#
|
10
|
+
# @return [TransmissionTable] the created instance.
|
11
|
+
def self.from_element(element, options={})
|
12
|
+
log = options[:log] || NcsNavigator::Mdes.default_logger
|
13
|
+
|
14
|
+
new(element['name']).tap do |table|
|
15
|
+
table.variables = element.
|
16
|
+
xpath('xs:complexType/xs:sequence/xs:element', SourceDocuments.xmlns).
|
17
|
+
collect { |col_elt| Variable.from_element(col_elt, options) }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
##
|
22
|
+
# @return [String] the machine name of the table. This is also the name of the XML
|
23
|
+
# element in the VDR export.
|
24
|
+
attr_reader :name
|
25
|
+
|
26
|
+
##
|
27
|
+
# @return [Array<Variable>] the variables that make up this
|
28
|
+
# table. (A relational model might call these the columns of this
|
29
|
+
# table.)
|
30
|
+
attr_accessor :variables
|
31
|
+
|
32
|
+
def initialize(name)
|
33
|
+
@name = name
|
34
|
+
end
|
35
|
+
|
36
|
+
##
|
37
|
+
# Search for a variable by name.
|
38
|
+
#
|
39
|
+
# @param variable_name [String] the name of the variable to look for.
|
40
|
+
# @return [Variable] the variable with the given name, if any
|
41
|
+
def [](variable_name)
|
42
|
+
variables.find { |c| c.name == variable_name }
|
43
|
+
end
|
44
|
+
|
45
|
+
##
|
46
|
+
# Provides a briefer inspection for cleaner IRB use.
|
47
|
+
#
|
48
|
+
# @return [String]
|
49
|
+
def inspect
|
50
|
+
"\#<#{self.class} name=#{name.inspect}>"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'ncs_navigator/mdes'
|
2
|
+
|
3
|
+
module NcsNavigator::Mdes
|
4
|
+
##
|
5
|
+
# A single field in the MDES. A relational model might also call
|
6
|
+
# this a column, but "variable" is what it's called in the MDES.
|
7
|
+
class Variable
|
8
|
+
##
|
9
|
+
# @return [String] the name of the variable
|
10
|
+
attr_reader :name
|
11
|
+
|
12
|
+
##
|
13
|
+
# @return [Boolean,:possible,:unknown,String] the PII category
|
14
|
+
# for the variable. `true` if it is definitely PII, `false` if
|
15
|
+
# it definitely is not, `:possible` if it was marked in the MDES
|
16
|
+
# as requiring manual review, `:unknown` if the MDES does not
|
17
|
+
# specify, or a string if the parsed value was not mappable to
|
18
|
+
# one of the above. Note that this value will always be truthy
|
19
|
+
# unless the MDES explicitly says that the variable is not PII.
|
20
|
+
attr_accessor :pii
|
21
|
+
|
22
|
+
##
|
23
|
+
# @return [:active,:new,:modified,:retired,String] the status of
|
24
|
+
# the variable in this version of the MDES. A String is returned
|
25
|
+
# if the source value doesn't match any of the expected values
|
26
|
+
# in the MDES.
|
27
|
+
attr_accessor :status
|
28
|
+
|
29
|
+
##
|
30
|
+
# @return [VariableType] the type of this variable.
|
31
|
+
attr_accessor :type
|
32
|
+
|
33
|
+
##
|
34
|
+
# Is the variable mandatory for a valid submission?
|
35
|
+
#
|
36
|
+
# @return [Boolean]
|
37
|
+
attr_accessor :required
|
38
|
+
alias :required? :required
|
39
|
+
|
40
|
+
class << self
|
41
|
+
##
|
42
|
+
# Examines the given parsed element and creates a new
|
43
|
+
# variable. The resulting variable has all the attributes set
|
44
|
+
# which can be set without reference to any other parts of the
|
45
|
+
# MDES outside of this one variable definition.
|
46
|
+
#
|
47
|
+
# @param [Nokogiri::Element] element the source xs:element
|
48
|
+
# @return [Variable] a new variable instance
|
49
|
+
def from_element(element, options={})
|
50
|
+
log = options[:log] || NcsNavigator::Mdes.default_logger
|
51
|
+
|
52
|
+
new(element['name']).tap do |var|
|
53
|
+
var.required = (element['nillable'] == 'false')
|
54
|
+
var.pii =
|
55
|
+
case element['pii']
|
56
|
+
when 'Y'; true;
|
57
|
+
when 'P'; :possible;
|
58
|
+
when nil; :unknown;
|
59
|
+
when ''; false;
|
60
|
+
else element['pii'];
|
61
|
+
end
|
62
|
+
var.status =
|
63
|
+
case element['status']
|
64
|
+
when '1'; :active;
|
65
|
+
when '2'; :new;
|
66
|
+
when '3'; :modified;
|
67
|
+
when '4'; :retired;
|
68
|
+
else element['status'];
|
69
|
+
end
|
70
|
+
var.type =
|
71
|
+
if element['type']
|
72
|
+
if element['type'] =~ /^xs:/
|
73
|
+
VariableType.xml_schema_type(element['type'].sub(/^xs:/, ''))
|
74
|
+
else
|
75
|
+
VariableType.reference(element['type'])
|
76
|
+
end
|
77
|
+
elsif element.elements.collect { |e| e.name } == %w(simpleType)
|
78
|
+
VariableType.from_xsd_simple_type(element.elements.first, options)
|
79
|
+
else
|
80
|
+
log.warn("Could not determine a type for variable #{var.name.inspect} on line #{element.line}")
|
81
|
+
nil
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def initialize(name)
|
88
|
+
@name = name
|
89
|
+
end
|
90
|
+
|
91
|
+
def constraints
|
92
|
+
@constraints ||= []
|
93
|
+
end
|
94
|
+
|
95
|
+
##
|
96
|
+
# If the {#type} of this instance is a reference to an NCS type,
|
97
|
+
# attempts to replace it with the full version from the given list
|
98
|
+
# of types.
|
99
|
+
#
|
100
|
+
# @param [Array<VariableType>] types
|
101
|
+
# @return [void]
|
102
|
+
def resolve_type!(types, options={})
|
103
|
+
log = options[:log] || NcsNavigator::Mdes.default_logger
|
104
|
+
|
105
|
+
return unless type && type.reference?
|
106
|
+
unless type.name =~ /^ncs:/
|
107
|
+
log.warn("Unknown reference namespace in type #{type.name.inspect} for #{name}")
|
108
|
+
end
|
109
|
+
|
110
|
+
ncs_type_name = type.name.sub(/^ncs:/, '')
|
111
|
+
match = types.find { |t| t.name == ncs_type_name }
|
112
|
+
if match
|
113
|
+
self.type = match
|
114
|
+
else
|
115
|
+
log.warn("Undefined type #{type.name} for #{name}.") if log
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,196 @@
|
|
1
|
+
require 'ncs_navigator/mdes'
|
2
|
+
|
3
|
+
module NcsNavigator::Mdes
|
4
|
+
##
|
5
|
+
# Encapsulates restrictions on the content of a {Variable}.
|
6
|
+
class VariableType
|
7
|
+
attr_reader :name
|
8
|
+
|
9
|
+
##
|
10
|
+
# @return [Symbol, nil] the XML Schema base type that this
|
11
|
+
# variable type is based on.
|
12
|
+
attr_accessor :base_type
|
13
|
+
|
14
|
+
##
|
15
|
+
# @return [Regexp, nil] a regular expression that valid values of this
|
16
|
+
# type must match.
|
17
|
+
attr_accessor :pattern
|
18
|
+
|
19
|
+
##
|
20
|
+
# @return [Fixnum, nil] the maximum length of a valid value of
|
21
|
+
# this type.
|
22
|
+
attr_accessor :max_length
|
23
|
+
|
24
|
+
##
|
25
|
+
# @return [Fixnum, nil] the minimum length of a valid value of
|
26
|
+
# this type.
|
27
|
+
attr_accessor :min_length
|
28
|
+
|
29
|
+
##
|
30
|
+
# @return [CodeList<CodeListEntry>, nil] the fixed list of values
|
31
|
+
# that are valid for this type.
|
32
|
+
attr_accessor :code_list
|
33
|
+
|
34
|
+
##
|
35
|
+
# @return [Boolean] whether this is a fully fleshed-out type or
|
36
|
+
# just a reference. If it is a reference, all fields except for
|
37
|
+
# {#name} should be ignored.
|
38
|
+
attr_accessor :reference
|
39
|
+
alias :reference? :reference
|
40
|
+
|
41
|
+
class << self
|
42
|
+
##
|
43
|
+
# @param [Nokogiri::XML::Element] st the `xs:simpleType` element
|
44
|
+
# from which to build the instance
|
45
|
+
# @param [Hash] options
|
46
|
+
# @option options [#warn] :log the logger to which to direct warnings
|
47
|
+
#
|
48
|
+
# @return [VariableType] a new instance based on the provided
|
49
|
+
# simple type.
|
50
|
+
def from_xsd_simple_type(st, options={})
|
51
|
+
log = options[:log] || NcsNavigator::Mdes.default_logger
|
52
|
+
|
53
|
+
restriction = st.xpath('xs:restriction[@base="xs:string"]', SourceDocuments.xmlns).first
|
54
|
+
unless restriction
|
55
|
+
log.warn "Unsupported restriction base in simpleType on line #{st.line}"
|
56
|
+
return
|
57
|
+
end
|
58
|
+
|
59
|
+
new(st['name']).tap do |vt|
|
60
|
+
vt.base_type = :string
|
61
|
+
restriction.elements.each do |elt|
|
62
|
+
case elt.name
|
63
|
+
when 'pattern'
|
64
|
+
p = elt['value']
|
65
|
+
vt.pattern =
|
66
|
+
begin
|
67
|
+
Regexp.new(p)
|
68
|
+
rescue RegexpError
|
69
|
+
log.warn("Uncompilable pattern #{p.inspect} in simpleType#{(' ' + vt.name.inspect) if vt.name} on line #{elt.line}")
|
70
|
+
nil
|
71
|
+
end
|
72
|
+
when 'maxLength'
|
73
|
+
vt.max_length = elt['value'].to_i
|
74
|
+
when 'minLength'
|
75
|
+
vt.min_length = elt['value'].to_i
|
76
|
+
when 'enumeration'
|
77
|
+
(vt.code_list ||= CodeList.new) << CodeListEntry.from_xsd_enumeration(elt)
|
78
|
+
if elt['desc'] =~ /\S/
|
79
|
+
if vt.code_list.description.nil?
|
80
|
+
vt.code_list.description = elt['desc']
|
81
|
+
elsif vt.code_list.description != elt['desc']
|
82
|
+
log.warn("Code list entry on line #{elt.line} unexpectedly has a different desc from the first entry")
|
83
|
+
end
|
84
|
+
end
|
85
|
+
else
|
86
|
+
log.warn "Unsupported restriction element #{elt.name.inspect} on line #{elt.line}"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
##
|
93
|
+
# Creates an instance that represents a reference with the given
|
94
|
+
# name.
|
95
|
+
#
|
96
|
+
# @return [VariableType] a new instance
|
97
|
+
def reference(name)
|
98
|
+
new(name).tap do |vt|
|
99
|
+
vt.reference = true
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
##
|
104
|
+
# Creates an instance corresponding to the given XML Schema
|
105
|
+
# simple base type.
|
106
|
+
#
|
107
|
+
# @return [VariableType] a new instance
|
108
|
+
def xml_schema_type(type_name)
|
109
|
+
new.tap do |vt|
|
110
|
+
vt.base_type = type_name.to_sym
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def initialize(name=nil)
|
116
|
+
@name = name
|
117
|
+
end
|
118
|
+
|
119
|
+
def inspect
|
120
|
+
attrs = [
|
121
|
+
[:name, name.inspect],
|
122
|
+
[:base_type, base_type.inspect],
|
123
|
+
[:reference, reference.inspect],
|
124
|
+
[:code_list, code_list ? "<#{code_list.size} entries>" : nil]
|
125
|
+
].reject { |k, v| v.nil? }.
|
126
|
+
collect { |k, v| "#{k}=#{v}" }
|
127
|
+
"#<#{self.class} #{attrs.join(' ')}>"
|
128
|
+
end
|
129
|
+
|
130
|
+
##
|
131
|
+
# A specialization of `Array` for code lists.
|
132
|
+
#
|
133
|
+
# @see VariableType#code_list
|
134
|
+
# @see CodeListEntry
|
135
|
+
class CodeList < Array
|
136
|
+
##
|
137
|
+
# @return [String,nil] the description of the code list if any.
|
138
|
+
attr_accessor :description
|
139
|
+
end
|
140
|
+
|
141
|
+
##
|
142
|
+
# A single entry in a code list.
|
143
|
+
#
|
144
|
+
# @see VariableType#code_list
|
145
|
+
# @see CodeList
|
146
|
+
class CodeListEntry
|
147
|
+
##
|
148
|
+
# @return [String] the local code value for the entry.
|
149
|
+
attr_reader :value
|
150
|
+
|
151
|
+
##
|
152
|
+
# @return [String] the human-readable label for the entry.
|
153
|
+
attr_accessor :label
|
154
|
+
|
155
|
+
##
|
156
|
+
# @return [String] the MDES's globally-unique identifier for
|
157
|
+
# this coded value.
|
158
|
+
attr_accessor :global_value
|
159
|
+
|
160
|
+
##
|
161
|
+
# @return [String] the name of MDES's master code list from
|
162
|
+
# which this value is derived.
|
163
|
+
attr_accessor :master_cl
|
164
|
+
|
165
|
+
class << self
|
166
|
+
##
|
167
|
+
# Creates a new instance from a `xs:enumeration` simple type
|
168
|
+
# restriction subelement.
|
169
|
+
#
|
170
|
+
# @param [Nokogiri::XML::Element] enum the `xs:enumeration`
|
171
|
+
# element.
|
172
|
+
# @param [Hash] options
|
173
|
+
# @option options [#warn] :log the logger to which to direct warnings
|
174
|
+
#
|
175
|
+
# @return [CodeListEntry]
|
176
|
+
def from_xsd_enumeration(enum, options={})
|
177
|
+
log = options[:log] || NcsNavigator::Mdes.default_logger
|
178
|
+
|
179
|
+
log.warn("Missing value for code list entry on line #{enum.line}") unless enum['value']
|
180
|
+
|
181
|
+
new(enum['value']).tap do |cle|
|
182
|
+
cle.label = enum['label']
|
183
|
+
cle.global_value = enum['global_value']
|
184
|
+
cle.master_cl = enum['master_cl']
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
def initialize(value)
|
190
|
+
@value = value
|
191
|
+
end
|
192
|
+
|
193
|
+
alias :to_s :value
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module NcsNavigator
|
4
|
+
module Mdes
|
5
|
+
autoload :VERSION, 'ncs_navigator/mdes/version'
|
6
|
+
|
7
|
+
autoload :SourceDocuments, 'ncs_navigator/mdes/source_documents'
|
8
|
+
autoload :Specification, 'ncs_navigator/mdes/specification'
|
9
|
+
autoload :TransmissionTable, 'ncs_navigator/mdes/transmission_table'
|
10
|
+
autoload :Variable, 'ncs_navigator/mdes/variable'
|
11
|
+
autoload :VariableType, 'ncs_navigator/mdes/variable_type'
|
12
|
+
|
13
|
+
##
|
14
|
+
# @return the default logger for this module when no other one is
|
15
|
+
# specified. It logs to standard error.
|
16
|
+
def self.default_logger
|
17
|
+
@default_logger ||= Logger.new($stderr)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
##
|
22
|
+
# @return [Mdes::Specification] a new {Mdes::Specification} for the given
|
23
|
+
# version.
|
24
|
+
def self.Mdes(version)
|
25
|
+
Mdes::Specification.new(version)
|
26
|
+
end
|
27
|
+
end
|
data/ncs_mdes.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "ncs_navigator/mdes/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "ncs_mdes"
|
7
|
+
s.version = NcsNavigator::Mdes::VERSION
|
8
|
+
s.authors = ["Rhett Sutphin"]
|
9
|
+
s.email = ["r-sutphin@northwestern.edu"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{A ruby API for various versions of the NCS MDES.}
|
12
|
+
s.description = %q{
|
13
|
+
Provides a consistent ruby interface to the project metainformation in the
|
14
|
+
National Children's Study's Master Data Element Specification.
|
15
|
+
}
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n") - ['irb']
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_dependency 'nokogiri', '~> 1.4'
|
23
|
+
|
24
|
+
s.add_development_dependency 'rspec', '~> 2.6'
|
25
|
+
s.add_development_dependency 'rake', '~> 0.9.2'
|
26
|
+
s.add_development_dependency 'yard', '~> 0.7.2'
|
27
|
+
end
|