ncs_mdes 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|