is no longer stripped: MathML is now explicitly defined in the
grammar (basicdoc-models#35), so its attributes (incl.
data-metanorma-numberformat) validate directly. metanorma-extension
(UnitsML etc.) and
# File 'lib/metanorma/validate/schema.rb', line 105defadd_ns_to_fragment(xml_fragment)f=Nokogiri::XML(xml_fragment,&:strict)f.errors.any?||f.root.nil?andreturnnilroot_tag=f.root.namef.root.namespaceorf=Nokogiri::XML(xml_fragment.sub(/<#{root_tag}([^>]*)>/,"<#{root_tag}\\1 xmlns='#{@conv.xml_namespace}'>"))frescueStandardErrornilend
#formattedstr_strip(doc) ⇒ Object
RelaxNG cannot cope well with wildcard attributes. So we strip
any attributes from FormattedString instances (which can contain
xs:any markup, and are signalled with @format) before validation.
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/metanorma/validate/schema.rb', line 146defformattedstr_strip(doc)doc.xpath(WILDCARD_ATTRS,"m"=>SVG_NS).eachdo|n|n.elements.eachdo|e|e.traversedo|e1|e1.element?ande1.each{|k,_v|e1.delete(k)}# rubocop:disable Style/HashEachMethods
endendenddoc.xpath("//m:svg","m"=>SVG_NS).each{|n|n.replace("<svg/>")}docend
# File 'lib/metanorma/validate/schema.rb', line 118deffragment_schema(root_element)temp_schema=Tempfile.new(["dynamic_schema",".rng"])temp_schema.write(<<~SCHEMA) <grammar xmlns="http://relaxng.org/ns/structure/1.0">
<include href="#{schema_location}">
<start combine="choice">
<ref name="#{root_element}"/>
</start>
</include>
</grammar>
SCHEMA
temp_schema.close[temp_schema,Nokogiri::XML::RelaxNG(File.open(temp_schema.path))]rescueStandardError# error because root_element is not in schema
[temp_schema,nil]end
#schema_file ⇒ Object
14
15
16
# File 'lib/metanorma/validate/schema.rb', line 14defschema_file"isodoc-compile.rng"end
#schema_location ⇒ Object
7
8
9
10
11
12
# File 'lib/metanorma/validate/schema.rb', line 7defschema_locationself.class.respond_to?(:_file)andret=self.class::_fileret||=caller_locations(1..1).first.absolute_pathret||=__FILE__File.join(File.dirname(ret),schema_file)end
#schema_validate(doc, schema) ⇒ Object
18
19
20
21
22
23
24
25
26
# File 'lib/metanorma/validate/schema.rb', line 18defschema_validate(doc,schema)Tempfile.open(["tmp",".xml"],encoding:"UTF-8")do|f|schema_validate1(f,doc,schema)rescueJing::Error=>e@conv.clean_abort("Jing failed with error: #{e}",doc)ensuref.close!endend
# File 'lib/metanorma/validate/schema.rb', line 33defschema_validate1(file,doc,schema)file.write(to_xml(doc))file.closeold_java_opts=ENV["_JAVA_OPTIONS"]ENV["_JAVA_OPTIONS"]="-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8"beginerrors=schema_validate_with_retry(schema,file.path)warn"Syntax Valid!"iferrors.none?errors.eachdo|e|@log.add("STANDOC_7","XML Line #{'%06d'%e[:line]}:#{e[:column]}",params:[e[:message]])endensure# Restore original _JAVA_OPTIONS
ENV["_JAVA_OPTIONS"]=old_java_optsendend
Retry Jing validation with exponential backoff to handle
"Too many open files" errors.
This can occur when validating large documents or when multiple
validations happen in quick succession, exhausting the system's
file descriptor limit.
Java's Jing validator opens multiple file handles for the JAR, schema,
and XML files, # and the OS may not clean them up fast enough.
# File 'lib/metanorma/validate/schema.rb', line 60defschema_validate_with_retry(schema,file_path,max_retries:3)retries=0begin# id_check: false disables jing's DTD-compatibility ID/IDREF check
# (emits -i). That check is namespace-blind and falsely reports
# "conflicting ID-types for id" once the embedded W3C MathML grammar
# (CommonAtt types id as xsd:ID) coexists with standoc's own xsd:ID
# id (basicdoc-models#35). Safe to disable: id/anchor uniqueness is
# enforced by content_validate (repeat_id_validate1 /
# repeat_anchor_validate1 -> STANDOC_36) and IDREF is text in
# Semantic XML (isodoc.rng). NB ruby-jing 0.0.3 polarity is inverted:
# id_check: false is what emits -i (verified against validate_spec).
Jing.new(schema,encoding:"UTF-8",id_check:false).validate(file_path)rescueJing::ExecutionError=>e# Check if this is a "Too many open files" error
ife.message.include?("Too many open files")&&retries<max_retriesretries+=1delay=0.1*(2**(retries-1))# Exponential backoff: 0.1s, 0.2s, 0.4s
warn"Jing validation encountered 'Too many open files' error. " \
"Retrying (attempt #{retries}/#{max_retries}) after #{delay}s delay..."sleep(delay)retryelse# Re-raise if not a file descriptor issue or max retries exceeded
raiseendendend
# File 'lib/metanorma/validate/schema.rb', line 89defvalidate_document_fragment(xml_fragment)f=add_ns_to_fragment(xml_fragment)orreturn[true,"Fragment is not well-formed XML, not validating"]begintemp_schema,schema=fragment_schema(f.root.name)schemaorreturn[false,"Did not expect element #{f.root.name}"]validation_errors=schema.validate(f)[validation_errors.none?do|x|x.to_s.include?("Did not expect element")end,validation_errors]ensuretemp_schema.unlinkendend