Validating XSD against XML In Ruby On Rails.(Part 2)
Ruby On Rails 5 Comments »Before I actually run into the development of the xsd helper, I would like to express some few points regarding how this helper will actually work:
1.The input to the xsd helper will be an xml file and an xsd file against which the ml is supposed to be validated
2. the Output will be the a message indicating the validation status.
So, here goes the actual helper i.e Xsd_Helper.rb
module XsdHelper
I require the fileutils and tempfile libs for file object manipulation
require ‘fileutils’
require ‘tempfile’
I define the FILE_HOME and the XML_STARTLET HOME.In the file home, I create 2 files finalxsd.xsd and finalxml.xml which we are going to see later.In the xmlstartlet home I keep the xmlstartlet library.Here I have kept the library in the public folder of our app.
FILE_HOME = “#{RAILS_ROOT}/public/temp”
XMLSTARTLET_HOME =”#{RAILS_ROOT}/public/xmlstartlet”
Now , we write the actual method which validates the xml against the xsd. We pass 2 parameters to the method i.e the xsdfile and the xmlfile
def validate_xml_to_xsd(xsdfile,xmlfile)
@temp_xsd =validate(xsdfile)
@temp_xml =validate(xmlfile)
We have to validate the xmlfiles and xsdfiles type in this case since in rails files below the size of 10kb are passed as a STRINGIO object and files above 10kb are passed as the TempFile Object . So, This validate method converts the STRINGIO object into the TEMPFILE object .
finalxsd = File.new(FILE_HOME+”/finalxsd.xsd”,”w”)
finalxml = File.new(FILE_HOME+”/finalxml.xml”,”w”)
Here,I create 2 new files in the FILE_HOME named finalxsd.xsd and finalxml.xsd.the purpose of these 2 files is, since, xmlstartlet library takes does not support the tempfile object
FileUtils.copy(”#{@temp_xsd.path}”,”#{finalxsd.path}”)
FileUtils.copy(”#{@temp_xml.path}”,”#{finalxml.path}”)
Here I copy the two file content from the temporary file to the respective xml and xsd file command_line=”#{XMLSTARTLET_HOME}/xml val -s “+ “#{finalxsd.path}” +’ ‘+”#{finalxml.path}”
result_string = %x[#{command_line}]
Then , I pass the two files to the xmlstratlet commandline utility for the actaual validation of the xml file
assess_validation_result(result_string)
The access validation result takes the result string as the input and customizes the output which is returned to our rails controller as a Boolean output
end
private
def assess_validation_result(result_string)
if (result_string=~/.+xml - invalid/).nil? then
true
else
raise result_string
end
end
def validate(file)
@file = file
# @file should contain file uploaded by HTTP
# it is either StringIO object (if file was smaller than 10Kb)
# or Tempfile (otherwise)
if not (@file.kind_of? StringIO or @file.kind_of? Tempfile)
return
end
if @file.kind_of? StringIO
# Yes, if @file is StringIO, create new Tempfile and copy everything to it
@real_file = Tempfile.new(”tempofile”)
while not @file.eof?
@real_file.write @file.read
end
else
# Most uploads will be Tempfiles
@real_file = @file
end
return @real_file
end
end
So,finally in the controller action, You can call the validate_xml_to_xsd(xsdfile,xmlfile) as ashoen below:
def input
if request.post? && !params.nil?
@validate_output = validate_xml_to_xsd(params[’fileinfo’][’xsd_file’],params[’fileinfo’][’xml_file’])
if(@validate_output == true)
flash[:notice] =”Your xml has been successfully validated”
end
render :action => ‘output’
else
render :action => ‘input’
flash[:notice] = “Failed to validate the xml file”
end
end
end








