0 comments
general
02 Mar 2010

XML Schema Generation

As we add more functionality to the IM Group API keeping up with the documentation changes can be painful. To keep on top of it, I made a useful git pre-commit script which reads and downloads xml data in order to keep the example files up to date.

With more people using the API I’ve started to receive requests for an up to date schema, so time to automate that as well…

Thankfully I found a very useful website that you can feed a url of some valid xml and it will give you a schema so all that need to be done was write some code to post data to the form and parse the result.

Now every time the API is updated new examples and schema are automatically downloaded!

The Code

The code reads a yaml array (from a local config file), posts the url for the xml file to the website, and saves the schema to a relative folder called ‘schema’.

Config

key: "api-key"
base_url: "http://api-key.api.co.uk"
schema_pages:
  news:
    url: "/news/limit/4.xml"
    filename: "news.xml"
  events:
    url: "/events/limit/4.xml"
    filename: "events.xml"
  offers:
    url: "/offers/limit/4.xml"
    filename: "offers.xml"
  cars:
    url: "/cars/all/limit/4.xml"
    filename: "cars.xml"  

Ruby Script

#!/usr/bin/ruby

require "yaml"
require "open-uri"
require "net/http"
require "CGI"


def get_schemas(schemas, baseurl, basefolder)
  generator_url = "http://www.xmlforasp.net/CodeBank/System_Xml_Schema/BuildSchema/BuildXMLSchema.aspx"
  schemas.each do |name, info |
    xurl = "#{baseurl}#{info['url']}"
    puts "  #{name}\n"
    result = post_schema(generator_url, xurl)
    if result
      writeOut = open("#{basefolder}#{info['filename']}", "wb")
      writeOut.write(CGI.unescapeHTML(result))
      writeOut.close
    else
      puts "!! ERROR - #{name} !!\n"
    end
  end
end

def post_schema(form_url, xml_url)
  #the __VIEWSTATE & __EVENTVALIDATION might change, not sure
  params = {'txtXML' => xml_url, 
            'rdoList'=>0,
            'btnGenerateSchema' => 'Generate Schema',
            '__VIEWSTATE' => '/wEPDwULLTE0NDc4ODY1NjZkZD8xIV1mw4aDZAU2p55EgLM0Vbe0',
            '__EVENTVALIDATION' => '/wEWBgKyvaD5BQKj+/r1AwKM1c/8AwKkyPGDAQK7yPGDAQK0p9vtDZZo8t55cXeilmxwatAyFeQD0njY'

            }
  uri = URI.parse(form_url)
  req = Net::HTTP::Post.new(form_url)
  req.set_form_data(params)
  res = Net::HTTP.new(uri.host, uri.port).start { |http| http.request(req) }
  raw = res.body
  if res.body =~ /<textarea name="txtSchema"[^>]*>(.*?)<\/textarea>/im
  	return $1
  else
  	return false;
  end
end

#MAIN
config = YAML::load_file("./example_config.yml");
schemas = config['schema_pages'].sort
puts "-- generating schema\n"
get_schemas(schemas, config['base_url'],"./schema/")
puts "-- done\n"

It won’t make the directories for you, and will fail if it doesn’t have permission to write to that folder.

The Files

All the files that are used…

blog comments powered by Disqus