#!/usr/bin/env jruby $LOAD_PATH.unshift(File.expand_path('./lib'), File.dirname(__FILE__)) require 'schematronium' raise "Not enough arguments" if ARGV.length < 2 Saxon::Processor.default.config[:line_numbering] = true # Disable a bunch of stuff in parser to prevent XXE vulnerabilities parser_options = Saxon::Processor.default.to_java.getUnderlyingConfiguration.parseOptions parser_options.add_parser_feature("http://apache.org/xml/features/disallow-doctype-decl", true) parser_options.add_parser_feature("http://xml.org/sax/features/external-general-entities", false) parser_options.add_parser_feature("http://xml.org/sax/features/external-parameter-entities", false) stron = Schematronium.new(ARGV.shift) @fnames = [] if ARGV.empty? @fnames = @fnames + Dir[File.join('.', "*.xml")] else ARGV.each do |arg| @fnames += case File.expand_path(arg) when File.method(:directory?).to_proc Dir[File.join(File.expand_path(arg), "*.xml")] when File.method(:file?).to_proc [File.expand_path(arg)] else [] end end end puts '' @fnames.each do |f| $stderr.write "Processing '#{f}'..." s_xml = Saxon.XML(File.open(f)) xml = stron.check(s_xml) xml.remove_namespaces! xml = xml.xpath("//failed-assert|//successful-report") xml.each do |el| el["line-number"] = s_xml.xpath(el.attr("location")).get_line_number end output = Nokogiri::XML::DocumentFragment.new(Nokogiri::XML::Document.new) file = output.add_child("").first counts = xml.group_by {|el| el.children.map(&:text).join.strip.gsub(/\s+/, ' ')}.reduce({}) {|res, (k,v)| res[k] = v.count; res} err_count = file.add_child("").first counts.each do |k,v| err_count.add_child("#{k}") end errs = file.add_child("").first errs.children = xml puts output $stderr.write " Finished\n" end puts ''