ruby3mf 0.2.1 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0e69399223f22bf72d431f634a3dae81966252da
4
- data.tar.gz: f8a87375c839cb3e42e00496104ee0c0a6a1c93f
3
+ metadata.gz: 2d2f6346320579794b80cb51d43cc89d2bfe62c5
4
+ data.tar.gz: 69c77fd6fe56952bc7e66b7bb0d8c113dbc35fc8
5
5
  SHA512:
6
- metadata.gz: 8ad2102f909a1df3f614010c4738b81e5b0ece6415d6f3f6cc47951151ed57f282b3150e4c2c581b41cd2685f46253df48c40117fbf0a323968a41502f594412
7
- data.tar.gz: 7c0182a9da87926ad9a76eb604a72dfc68926720b14e7174a4672d8c8f18773bdfb835b6fff4c428983bdb9dbdf169b7980b55fec53aea070d697a98c8e36322
6
+ metadata.gz: 56d2dbe4baa8689c8eaa1f227a407c960204f820d27c5f907d3b0201baa8c3b5a96c05f25abb4f8f6d4df88fc6b8975ec74d774c2972c8b4d0d8de7a8c556945
7
+ data.tar.gz: 7c934b3b61c37585696697e644fb63d4ffe516d07e5f10c7fde335baac6e2b879db3de0c6d91c6a1574432bb053de3d69289986f4ad63952b742a63172178d2c
data/bin/batch.rb CHANGED
@@ -1,21 +1,22 @@
1
- #!/usr/bin/env ruby
2
-
3
- require_relative '../lib/ruby3mf'
4
-
5
- files = Dir["spec/ruby3mf-testfiles/#{ARGV[0] || "failing_cases"}/*.#{ARGV[1] || '3mf'}"]
6
-
7
- files.each do |file|
8
- begin
9
- Log3mf.reset_log
10
- doc = Document.read(file)
11
- errors = Log3mf.entries(:error, :fatal_error)
12
-
13
- puts "=" * 100
14
- puts "Validating file: #{file}"
15
- errors.each do |ent|
16
- h = { context: ent[0], severity: ent[1], message: ent[2] }
17
- puts h
18
- end
19
- rescue
20
- end
21
- end
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/ruby3mf'
4
+
5
+ files = Dir["spec/ruby3mf-testfiles/#{ARGV[0] || "failing_cases"}/*.#{ARGV[1] || '3mf'}"]
6
+
7
+ files.each do |file|
8
+ begin
9
+ Log3mf.reset_log
10
+ doc = Document.read(file)
11
+ errors = Log3mf.entries(:error, :fatal_error)
12
+
13
+ puts "=" * 100
14
+ puts "Validating file: #{file}"
15
+
16
+ errors.each do |ent|
17
+ h = { context: ent[0], severity: ent[1], message: ent[2] }
18
+ puts h
19
+ end
20
+ rescue
21
+ end
22
+ end
data/bin/cli.rb CHANGED
@@ -10,3 +10,6 @@ errors.each do |ent|
10
10
  h = { file: filename, context: ent[0], severity: ent[1], message: ent[2] }
11
11
  puts h
12
12
  end
13
+
14
+ # set exit code for suite test usage
15
+ exit errors.size == 0
data/bin/suite_test.sh ADDED
@@ -0,0 +1,39 @@
1
+ #!/bin/bash
2
+
3
+ MATCH=$1
4
+ OUTFILE=suite_test.txt
5
+ GOOD_FILES=../3mf-test-suite/Positive/${MATCH}*.3mf
6
+ BAD_FILES=../3mf-test-suite/Negative/${MATCH}*.3mf
7
+
8
+ echo "Test Suite: filter: ${MATCH}"
9
+ printf "\n\nTest Suite: filter: ${MATCH} - $(date)\n" >> ${OUTFILE}
10
+
11
+ echo "Positive Files -------------"
12
+ printf "\nPositive Files -------------\n" >> ${OUTFILE}
13
+ for filename in ${GOOD_FILES}; do
14
+ if [ -f ${filename} ]; then
15
+ echo " Validating ${filename}"
16
+ result=$(( ~/src/ruby3mf/bin/cli.rb ${filename} ) 2>&1)
17
+ if [ $? -ne 0 ]; then
18
+ echo " Failed!"
19
+ printf " ${filename}\n $result\n" >> ${OUTFILE}
20
+ fi
21
+ fi
22
+ done
23
+
24
+ echo "Negative Files -------------"
25
+ printf "\nNegative Files -------------\n" >> suite_test.txt
26
+ for filename in ${BAD_FILES}; do
27
+ if [ -f ${filename} ]; then
28
+ echo " Validating ${filename}"
29
+ result=$(( ~/src/ruby3mf/bin/cli.rb ${filename} ) 2>&1)
30
+ if [ $? -eq 0 ]; then
31
+ echo " Passed!"
32
+ printf " ${filename} - No Errors found!\n" >> ${OUTFILE}
33
+ fi
34
+ fi
35
+ done
36
+
37
+ echo "All Done."
38
+ printf "Completed -- $(date)\n\n" >> ${OUTFILE}
39
+
data/lib/ruby3mf.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require_relative "ruby3mf/version"
2
2
  require_relative "ruby3mf/interpolation"
3
+ require_relative "ruby3mf/schema_files"
3
4
  require_relative "ruby3mf/log3mf"
4
5
  require_relative "ruby3mf/document"
5
6
  require_relative "ruby3mf/content_types"
@@ -3,7 +3,7 @@
3
3
  targetNamespace="http://schemas.microsoft.com/3dmanufacturing/core/2015/02" elementFormDefault="unqualified"
4
4
  attributeFormDefault="unqualified" blockDefault="#all">
5
5
  <xs:import namespace="http://www.w3.org/XML/1998/namespace"
6
- schemaLocation="http://www.w3.org/2001/xml.xsd"/>
6
+ schemaLocation= "<%= SchemaFiles::SchemaLocation %>" />
7
7
  <xs:annotation>
8
8
  <xs:documentation><![CDATA[
9
9
  Schema notes:
@@ -2,6 +2,7 @@ class ContentTypes
2
2
 
3
3
  def self.parse(zip_entry)
4
4
  found_types={}
5
+ found_overrides={}
5
6
 
6
7
  Log3mf.context "parse" do |l|
7
8
  begin
@@ -18,13 +19,20 @@ class ContentTypes
18
19
  types_node = doc.children.first
19
20
  types_node.children.each do |node|
20
21
  l.context node.name do |l|
21
- unless node.name == 'Default'
22
- l.warning "[Content_Types].xml:#{node.line} contains unexpected element #{node.name}", page: 10
23
- else
22
+ if node.name == 'Default'
24
23
  # l.error "[Content_Types].xml:#{node.line} contains Default node without defined Extension attribute" unless node['Extension'].is_a? String
25
24
  # l.error "[Content_Types].xml:#{node.line} contains Default node with unexpected ContentType \"#{node['ContentType']}\"", page: 10 unless all_types.include? node['ContentType']
26
25
  l.info "Setting type hash #{node['Extension']}=#{node['ContentType']}"
26
+
27
+ l.error :duplicate_content_extension_types if !found_types[node['Extension']].nil?
27
28
  found_types[node['Extension']] = node['ContentType']
29
+ elsif node.name == 'Override'
30
+ l.error :empty_override_part_name if node['PartName'].empty?
31
+
32
+ l.error :duplicate_content_override_types if !found_overrides[node['PartName']].nil?
33
+ found_overrides[node['PartName']] = node['ContentType']
34
+ else
35
+ l.warning "[Content_Types].xml:#{node.line} contains unexpected element #{node.name}", page: 10
28
36
  end
29
37
  end
30
38
  end
@@ -15,6 +15,18 @@ class Document
15
15
  TEXTURE_TYPE = 'http://schemas.microsoft.com/3dmanufacturing/2013/01/3dtexture'
16
16
  PRINT_TICKET_TYPE = 'http://schemas.microsoft.com/3dmanufacturing/2013/01/printticket'
17
17
 
18
+ # Image Content Types
19
+ THUMBNAIL_TYPES = %w[image/jpeg image/png].freeze
20
+ TEXTURE_TYPES = %w[image/jpeg image/png application/vnd.ms-package.3dmanufacturing-3dmodeltexture].freeze
21
+
22
+ # Relationship to valid Content types
23
+ REL_TO_CONTENT_TYPES = {
24
+ MODEL_TYPE => 'application/vnd.ms-package.3dmanufacturing-3dmodel+xml',
25
+ PRINT_TICKET_TYPE => 'application/vnd.ms-printing.printticket+xml',
26
+ TEXTURE_TYPE => TEXTURE_TYPES,
27
+ THUMBNAIL_TYPE => THUMBNAIL_TYPES
28
+ }
29
+
18
30
  # Relationship Type => Class validating relationship type
19
31
  RELATIONSHIP_TYPES = {
20
32
  MODEL_TYPE => {klass: 'Model3mf', collection: :models},
@@ -23,15 +35,13 @@ class Document
23
35
  PRINT_TICKET_TYPE => {}
24
36
  }
25
37
 
26
- TEXTURE_TYPES = %w[image/jpeg image/png application/vnd.ms-package.3dmanufacturing-3dmodeltexture]
27
-
28
38
  def initialize(zip_filename)
29
39
  self.models=[]
30
40
  self.thumbnails=[]
31
41
  self.textures=[]
32
42
  self.objects={}
33
43
  self.relationships={}
34
- self.types=[]
44
+ self.types={}
35
45
  self.parts=[]
36
46
  @zip_filename = zip_filename
37
47
  end
@@ -96,10 +106,11 @@ class Document
96
106
  if content_type_match
97
107
  m.types = ContentTypes.parse(content_type_match)
98
108
  model_extension = m.types.key('application/vnd.ms-package.3dmanufacturing-3dmodel+xml')
109
+ model_extension = model_extension.downcase unless model_extension.nil?
99
110
  model_file = zip_file.glob("**/*.#{model_extension}").first
100
111
  l.error :no_3d_model, extension: model_extension if model_file.nil?
101
112
  else
102
- l.error 'Missing required file: [Content_Types].xml', page: 4
113
+ l.fatal_error 'Missing required file: [Content_Types].xml', page: 4
103
114
  end
104
115
  end
105
116
 
@@ -136,6 +147,20 @@ class Document
136
147
  l.error :err_uri_relative_path if target.include? '/../'
137
148
  relationship_file = zip_file.glob(target).first
138
149
 
150
+ # check that relationships are valid; extensions and relationship types must jive
151
+ extension = File.extname(target).strip.downcase[1..-1]
152
+
153
+ content_type = m.types[extension]
154
+ rel_type = rel[:type]
155
+ expected_content_type = REL_TO_CONTENT_TYPES[rel_type]
156
+
157
+ if (expected_content_type)
158
+ l.error :missing_extension_in_content_types, ext: extension unless content_type
159
+ l.error :resource_contentype_invalid, bt: content_type, rt: rel[:target] unless (!content_type.nil? && expected_content_type.include?(content_type))
160
+ else
161
+ l.info "found unrecognized relationship type: #{rel_type}"
162
+ end
163
+
139
164
  if relationship_file
140
165
  relationship_type = RELATIONSHIP_TYPES[rel[:type]]
141
166
  if relationship_type.nil?
@@ -1,5 +1,5 @@
1
1
  resource_contentype_invalid:
2
- msg: "Resource in model has invalid contenttype %{bt}"
2
+ msg: "Relationship target %{rt} resource has invalid contenttype %{bt}"
3
3
  page: 10
4
4
  err_uri_empty_segment:
5
5
  msg: 'No segment of a 3MF part name path may be empty'
@@ -70,12 +70,19 @@ invalid_texture_file_type:
70
70
  missing_content_types:
71
71
  msg: "Missing required file: [Content_Types].xml"
72
72
  page: 4
73
+ missing_extension_in_content_types:
74
+ msg: "Missing extension '%{ext}' in [Content_Types].xml"
75
+ page: 10
73
76
  missing_dot_rels_file:
74
77
  msg: "Missing required file _rels/.rels"
75
78
  page: 4
76
79
  missing_rels_folder:
77
80
  msg: "Missing required file _rels/.rels"
78
81
  page: 4
82
+ non_unique_rel_id:
83
+ msg: "The ID value '%{id}' appears more than once in '%{file}'. Within a rels file, all ID's must be unique"
84
+ page: 8 #TODO:change this to page 23 of the OPC spec once logging supports linking to that spec
85
+ spec: opc
79
86
  multiple_relationships:
80
87
  msg: "There MUST NOT be more than one relationship of a given relationship type from one part to a second part"
81
88
  page: 10
@@ -148,3 +155,15 @@ non_distinct_indices:
148
155
  has_improper_base_color:
149
156
  msg: "An sRGB color MUST be specified with a value of a 6 or 8 digit hexadecimal number"
150
157
  page: 35
158
+ duplicate_content_extension_types:
159
+ msg: "Only one ContentType definition is allowed per extension"
160
+ page: 8
161
+ invalid_image_content_type:
162
+ msg: "Invalid content type for %{extension}"
163
+ page: 22
164
+ duplicate_content_override_types:
165
+ msg: "Only one override is allowed per part"
166
+ page: 8
167
+ empty_override_part_name:
168
+ msg: "Overrides can't have empty partname"
169
+ page: 8
@@ -65,7 +65,7 @@ class Log3mf
65
65
  def method_missing(name, *args, &block)
66
66
  if LOG_LEVELS.include? name.to_sym
67
67
  log(name.to_sym, *args)
68
- else
68
+ else+
69
69
  super
70
70
  end
71
71
  end
@@ -73,6 +73,7 @@ class Log3mf
73
73
  def log(severity, message, options = {})
74
74
  error = @errormap.fetch(message.to_s) { {"msg" => message.to_s, "page" => nil } }
75
75
  options[:page] = error["page"] unless options[:page]
76
+ options[:spec] = error["spec"] unless options[:spec]
76
77
  message = interpolate(error["msg"], options)
77
78
  @log_list << ["#{@context_stack.join("/")}", severity, message, options] unless severity==:debug && ENV['LOGDEBUG'].nil?
78
79
  raise FatalError if severity == :fatal_error
@@ -100,7 +101,9 @@ class Log3mf
100
101
  core: 'http://3mf.io/wp-content/uploads/2016/03/3MFcoreSpec_1.1.pdf',
101
102
  material: 'http://3mf.io/wp-content/uploads/2015/04/3MFmaterialsSpec_1.0.1.pdf',
102
103
  production: 'http://3mf.io/wp-content/uploads/2016/07/3MFproductionSpec.pdf',
103
- slice: 'http://3mf.io/wp-content/uploads/2016/07/3MFsliceSpec.pdf'
104
+ slice: 'http://3mf.io/wp-content/uploads/2016/07/3MFsliceSpec.pdf',
105
+ #opc: 'http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-376,%20Fourth%20Edition,%20Part%202%20-%20Open%20Packaging%20Conventions.zip'
106
+ opc: 'http://3mf.io/wp-content/uploads/2016/03/3MFcoreSpec_1.1.pdf'
104
107
  }
105
108
  "#{doc_urls[spec]}#page=#{page}"
106
109
  end
@@ -1,14 +1,11 @@
1
1
  class Model3mf
2
2
 
3
- VALID_UNITS = ['micron', 'millimeter', 'centimeter', 'meter', 'inch', 'foot'].freeze
4
3
  VALID_EXTENSIONS = {
5
4
  'http://schemas.microsoft.com/3dmanufacturing/slice/2015/07' => {},
6
5
  'http://schemas.microsoft.com/3dmanufacturing/material/2015/02' => {},
7
6
  'http://schemas.microsoft.com/3dmanufacturing/production/2015/06' => {},
8
7
  }.freeze
9
8
 
10
- SCHEMA = '3MFcoreSpec_1.1.xsd'
11
-
12
9
  VALID_CORE_METADATA_NAMES = ['Title', 'Designer', 'Description', 'Copyright', 'LicenseTerms', 'Rating', 'CreationDate', 'ModificationDate'].freeze
13
10
 
14
11
  def self.parse(document, zip_entry)
@@ -16,7 +13,7 @@ class Model3mf
16
13
 
17
14
  Log3mf.context "parsing model" do |l|
18
15
  begin
19
- model_doc = XmlVal.validate_parse(zip_entry, SCHEMA)
16
+ model_doc = XmlVal.validate_parse(zip_entry, SchemaFiles::SchemaTemplate)
20
17
  rescue Nokogiri::XML::SyntaxError => e
21
18
  l.fatal_error "Model file invalid XML. Exception #{e}"
22
19
  end
@@ -15,6 +15,7 @@ class Relationships
15
15
  relationship_elements.each do |node|
16
16
  if node.is_a?(Nokogiri::XML::Element) && node.name == "Relationship"
17
17
  l.error :multiple_relationships if (relationships.select { |r| r[:target] == node['Target'] && r[:type] == node['Type'] }.size > 0)
18
+ l.error :non_unique_rel_id, :file => zip_entry.name, :id => node['Id'] if (relationships.select { |r| r[:id] == node['Id'] }.size > 0)
18
19
  relationships << {target: node['Target'], type: node['Type'], id: node['Id']}
19
20
  l.info "adding relationship: #{relationships.last.inspect}"
20
21
  else
@@ -0,0 +1,12 @@
1
+ require 'erb'
2
+
3
+ class SchemaFiles
4
+
5
+ SchemaTemplate = File.join(File.dirname(__FILE__), "3MFcoreSpec_1.1.xsd.template")
6
+ SchemaLocation = File.join(File.dirname(__FILE__), "xml.xsd")
7
+
8
+ def self.render(template)
9
+ ERB.new(template).result( binding )
10
+ end
11
+
12
+ end
@@ -1,3 +1,3 @@
1
1
  module Ruby3mf
2
- VERSION = "0.2.1"
2
+ VERSION = "0.2.3"
3
3
  end
@@ -0,0 +1,286 @@
1
+ <?xml version='1.0'?>
2
+ <?xml-stylesheet href="../2008/09/xsd.xsl" type="text/xsl"?>
3
+ <xs:schema targetNamespace="http://www.w3.org/XML/1998/namespace"
4
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
5
+ xmlns ="http://www.w3.org/1999/xhtml"
6
+ xml:lang="en">
7
+
8
+ <xs:annotation>
9
+ <xs:documentation>
10
+ <div>
11
+ <h1>About the XML namespace</h1>
12
+
13
+ <div class="bodytext">
14
+ <p>
15
+ This schema document describes the XML namespace, in a form
16
+ suitable for import by other schema documents.
17
+ </p>
18
+ <p>
19
+ See <a href="http://www.w3.org/XML/1998/namespace.html">
20
+ http://www.w3.org/XML/1998/namespace.html</a> and
21
+ <a href="http://www.w3.org/TR/REC-xml">
22
+ http://www.w3.org/TR/REC-xml</a> for information
23
+ about this namespace.
24
+ </p>
25
+ <p>
26
+ Note that local names in this namespace are intended to be
27
+ defined only by the World Wide Web Consortium or its subgroups.
28
+ The names currently defined in this namespace are listed below.
29
+ They should not be used with conflicting semantics by any Working
30
+ Group, specification, or document instance.
31
+ </p>
32
+ <p>
33
+ See further below in this document for more information about <a
34
+ href="#usage">how to refer to this schema document from your own
35
+ XSD schema documents</a> and about <a href="#nsversioning">the
36
+ namespace-versioning policy governing this schema document</a>.
37
+ </p>
38
+ </div>
39
+ </div>
40
+ </xs:documentation>
41
+ </xs:annotation>
42
+
43
+ <xs:attribute name="lang">
44
+ <xs:annotation>
45
+ <xs:documentation>
46
+ <div>
47
+
48
+ <h3>lang (as an attribute name)</h3>
49
+ <p>
50
+ denotes an attribute whose value
51
+ is a language code for the natural language of the content of
52
+ any element; its value is inherited. This name is reserved
53
+ by virtue of its definition in the XML specification.</p>
54
+
55
+ </div>
56
+ <div>
57
+ <h4>Notes</h4>
58
+ <p>
59
+ Attempting to install the relevant ISO 2- and 3-letter
60
+ codes as the enumerated possible values is probably never
61
+ going to be a realistic possibility.
62
+ </p>
63
+ <p>
64
+ See BCP 47 at <a href="http://www.rfc-editor.org/rfc/bcp/bcp47.txt">
65
+ http://www.rfc-editor.org/rfc/bcp/bcp47.txt</a>
66
+ and the IANA language subtag registry at
67
+ <a href="http://www.iana.org/assignments/language-subtag-registry">
68
+ http://www.iana.org/assignments/language-subtag-registry</a>
69
+ for further information.
70
+ </p>
71
+ <p>
72
+ The union allows for the 'un-declaration' of xml:lang with
73
+ the empty string.
74
+ </p>
75
+ </div>
76
+ </xs:documentation>
77
+ </xs:annotation>
78
+ <xs:simpleType>
79
+ <xs:union memberTypes="xs:language">
80
+ <xs:simpleType>
81
+ <xs:restriction base="xs:string">
82
+ <xs:enumeration value=""/>
83
+ </xs:restriction>
84
+ </xs:simpleType>
85
+ </xs:union>
86
+ </xs:simpleType>
87
+ </xs:attribute>
88
+
89
+ <xs:attribute name="space">
90
+ <xs:annotation>
91
+ <xs:documentation>
92
+ <div>
93
+
94
+ <h3>space (as an attribute name)</h3>
95
+ <p>
96
+ denotes an attribute whose
97
+ value is a keyword indicating what whitespace processing
98
+ discipline is intended for the content of the element; its
99
+ value is inherited. This name is reserved by virtue of its
100
+ definition in the XML specification.</p>
101
+
102
+ </div>
103
+ </xs:documentation>
104
+ </xs:annotation>
105
+ <xs:simpleType>
106
+ <xs:restriction base="xs:NCName">
107
+ <xs:enumeration value="default"/>
108
+ <xs:enumeration value="preserve"/>
109
+ </xs:restriction>
110
+ </xs:simpleType>
111
+ </xs:attribute>
112
+
113
+ <xs:attribute name="base" type="xs:anyURI"> <xs:annotation>
114
+ <xs:documentation>
115
+ <div>
116
+
117
+ <h3>base (as an attribute name)</h3>
118
+ <p>
119
+ denotes an attribute whose value
120
+ provides a URI to be used as the base for interpreting any
121
+ relative URIs in the scope of the element on which it
122
+ appears; its value is inherited. This name is reserved
123
+ by virtue of its definition in the XML Base specification.</p>
124
+
125
+ <p>
126
+ See <a
127
+ href="http://www.w3.org/TR/xmlbase/">http://www.w3.org/TR/xmlbase/</a>
128
+ for information about this attribute.
129
+ </p>
130
+ </div>
131
+ </xs:documentation>
132
+ </xs:annotation>
133
+ </xs:attribute>
134
+
135
+ <xs:attribute name="id" type="xs:ID">
136
+ <xs:annotation>
137
+ <xs:documentation>
138
+ <div>
139
+
140
+ <h3>id (as an attribute name)</h3>
141
+ <p>
142
+ denotes an attribute whose value
143
+ should be interpreted as if declared to be of type ID.
144
+ This name is reserved by virtue of its definition in the
145
+ xml:id specification.</p>
146
+
147
+ <p>
148
+ See <a
149
+ href="http://www.w3.org/TR/xml-id/">http://www.w3.org/TR/xml-id/</a>
150
+ for information about this attribute.
151
+ </p>
152
+ </div>
153
+ </xs:documentation>
154
+ </xs:annotation>
155
+ </xs:attribute>
156
+
157
+ <xs:attributeGroup name="specialAttrs">
158
+ <xs:attribute ref="xml:base"/>
159
+ <xs:attribute ref="xml:lang"/>
160
+ <xs:attribute ref="xml:space"/>
161
+ <xs:attribute ref="xml:id"/>
162
+ </xs:attributeGroup>
163
+
164
+ <xs:annotation>
165
+ <xs:documentation>
166
+ <div>
167
+
168
+ <h3>Father (in any context at all)</h3>
169
+
170
+ <div class="bodytext">
171
+ <p>
172
+ denotes Jon Bosak, the chair of
173
+ the original XML Working Group. This name is reserved by
174
+ the following decision of the W3C XML Plenary and
175
+ XML Coordination groups:
176
+ </p>
177
+ <blockquote>
178
+ <p>
179
+ In appreciation for his vision, leadership and
180
+ dedication the W3C XML Plenary on this 10th day of
181
+ February, 2000, reserves for Jon Bosak in perpetuity
182
+ the XML name "xml:Father".
183
+ </p>
184
+ </blockquote>
185
+ </div>
186
+ </div>
187
+ </xs:documentation>
188
+ </xs:annotation>
189
+
190
+ <xs:annotation>
191
+ <xs:documentation>
192
+ <div xml:id="usage" id="usage">
193
+ <h2><a name="usage">About this schema document</a></h2>
194
+
195
+ <div class="bodytext">
196
+ <p>
197
+ This schema defines attributes and an attribute group suitable
198
+ for use by schemas wishing to allow <code>xml:base</code>,
199
+ <code>xml:lang</code>, <code>xml:space</code> or
200
+ <code>xml:id</code> attributes on elements they define.
201
+ </p>
202
+ <p>
203
+ To enable this, such a schema must import this schema for
204
+ the XML namespace, e.g. as follows:
205
+ </p>
206
+ <pre>
207
+ &lt;schema . . .>
208
+ . . .
209
+ &lt;import namespace="http://www.w3.org/XML/1998/namespace"
210
+ schemaLocation="http://www.w3.org/2001/xml.xsd"/>
211
+ </pre>
212
+ <p>
213
+ or
214
+ </p>
215
+ <pre>
216
+ &lt;import namespace="http://www.w3.org/XML/1998/namespace"
217
+ schemaLocation="http://www.w3.org/2009/01/xml.xsd"/>
218
+ </pre>
219
+ <p>
220
+ Subsequently, qualified reference to any of the attributes or the
221
+ group defined below will have the desired effect, e.g.
222
+ </p>
223
+ <pre>
224
+ &lt;type . . .>
225
+ . . .
226
+ &lt;attributeGroup ref="xml:specialAttrs"/>
227
+ </pre>
228
+ <p>
229
+ will define a type which will schema-validate an instance element
230
+ with any of those attributes.
231
+ </p>
232
+ </div>
233
+ </div>
234
+ </xs:documentation>
235
+ </xs:annotation>
236
+
237
+ <xs:annotation>
238
+ <xs:documentation>
239
+ <div id="nsversioning" xml:id="nsversioning">
240
+ <h2><a name="nsversioning">Versioning policy for this schema document</a></h2>
241
+ <div class="bodytext">
242
+ <p>
243
+ In keeping with the XML Schema WG's standard versioning
244
+ policy, this schema document will persist at
245
+ <a href="http://www.w3.org/2009/01/xml.xsd">
246
+ http://www.w3.org/2009/01/xml.xsd</a>.
247
+ </p>
248
+ <p>
249
+ At the date of issue it can also be found at
250
+ <a href="http://www.w3.org/2001/xml.xsd">
251
+ http://www.w3.org/2001/xml.xsd</a>.
252
+ </p>
253
+ <p>
254
+ The schema document at that URI may however change in the future,
255
+ in order to remain compatible with the latest version of XML
256
+ Schema itself, or with the XML namespace itself. In other words,
257
+ if the XML Schema or XML namespaces change, the version of this
258
+ document at <a href="http://www.w3.org/2001/xml.xsd">
259
+ http://www.w3.org/2001/xml.xsd
260
+ </a>
261
+ will change accordingly; the version at
262
+ <a href="http://www.w3.org/2009/01/xml.xsd">
263
+ http://www.w3.org/2009/01/xml.xsd
264
+ </a>
265
+ will not change.
266
+ </p>
267
+ <p>
268
+ Previous dated (and unchanging) versions of this schema
269
+ document are at:
270
+ </p>
271
+ <ul>
272
+ <li><a href="http://www.w3.org/2009/01/xml.xsd">
273
+ http://www.w3.org/2009/01/xml.xsd</a></li>
274
+ <li><a href="http://www.w3.org/2007/08/xml.xsd">
275
+ http://www.w3.org/2007/08/xml.xsd</a></li>
276
+ <li><a href="http://www.w3.org/2004/10/xml.xsd">
277
+ http://www.w3.org/2004/10/xml.xsd</a></li>
278
+ <li><a href="http://www.w3.org/2001/03/xml.xsd">
279
+ http://www.w3.org/2001/03/xml.xsd</a></li>
280
+ </ul>
281
+ </div>
282
+ </div>
283
+ </xs:documentation>
284
+ </xs:annotation>
285
+
286
+ </xs:schema>
@@ -2,7 +2,7 @@ require 'nokogiri'
2
2
 
3
3
  class XmlVal
4
4
 
5
- def self.validate_parse(xml_file, schema_name=nil)
5
+ def self.validate_parse(xml_file, schema_name = nil)
6
6
  doc = Nokogiri::XML(xml_file.get_input_stream) do |config|
7
7
  config.strict.nonet.noblanks
8
8
  end
@@ -10,7 +10,14 @@ class XmlVal
10
10
  doc
11
11
  end
12
12
 
13
- def self.validate(file, document, schema_filename=nil)
13
+ def self.open_schema_file(file)
14
+ File.open(file, "r") do |file|
15
+ template = file.read
16
+ yield(SchemaFiles.render(template))
17
+ end
18
+ end
19
+
20
+ def self.validate(file, document, schema_filename = nil)
14
21
  Log3mf.context "validations" do |l|
15
22
  l.error :has_xml_space_attribute if space_attribute_exists?(document)
16
23
  l.error :wrong_encoding if xml_not_utf8_encoded?(document)
@@ -20,8 +27,8 @@ class XmlVal
20
27
 
21
28
  if schema_filename
22
29
  Log3mf.context "validating core schema" do |l|
23
- File.open(File.join(File.dirname(__FILE__), schema_filename), "r") do |file|
24
- xsd = Nokogiri::XML::Schema(file.read)
30
+ open_schema_file(schema_filename) do |content|
31
+ xsd = Nokogiri::XML::Schema(content)
25
32
  puts "the schema is NIL!" if xsd.nil?
26
33
  core_schema_errors = xsd.validate(document)
27
34
  l.error :invalid_xml_core if core_schema_errors.size > 0
@@ -39,7 +46,7 @@ class XmlVal
39
46
  end
40
47
 
41
48
  def self.objects_not_referenced?(document)
42
- document.css('object').map { |x| x.attributes["id"].value } != document.css('item').map { |x| x.attributes["objectid"].value }
49
+ document.css('object').map { |x| x.attributes["id"].value } != document.css('build/item').map { |x| x.attributes["objectid"].value }
43
50
  end
44
51
 
45
52
  def self.bad_floating_numbers?(document)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby3mf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Whitmarsh, Jeff Porter, and William Hertling
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-01-19 00:00:00.000000000 Z
11
+ date: 2017-01-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -147,8 +147,9 @@ files:
147
147
  - bin/folder_test.sh
148
148
  - bin/setup
149
149
  - bin/suite.rb
150
+ - bin/suite_test.sh
150
151
  - lib/ruby3mf.rb
151
- - lib/ruby3mf/3MFcoreSpec_1.1.xsd
152
+ - lib/ruby3mf/3MFcoreSpec_1.1.xsd.template
152
153
  - lib/ruby3mf/content_types.rb
153
154
  - lib/ruby3mf/document.rb
154
155
  - lib/ruby3mf/edge_list.rb
@@ -158,9 +159,11 @@ files:
158
159
  - lib/ruby3mf/mesh_analyzer.rb
159
160
  - lib/ruby3mf/model3mf.rb
160
161
  - lib/ruby3mf/relationships.rb
162
+ - lib/ruby3mf/schema_files.rb
161
163
  - lib/ruby3mf/texture3mf.rb
162
164
  - lib/ruby3mf/thumbnail3mf.rb
163
165
  - lib/ruby3mf/version.rb
166
+ - lib/ruby3mf/xml.xsd
164
167
  - lib/ruby3mf/xml_val.rb
165
168
  - ruby3mf.gemspec
166
169
  homepage: https://github.com/IPGPTP/ruby3mf