davidmoten / xsd-forms

Generates web forms from xml schema documents (xsd)
137 stars 51 forks source link

xsd-forms


You want to make a web form that submits structured data (XML/JSON).

xsd-forms generates a web form for you based on an xml schema (XSD) that has been annotated with some presentation information.

xsd-forms has been deployed to a freely available web service for your convenience and immediate testing.

The form is javascript/html only and performs all validation using javascript.

This project is written in Scala with a small amount of Java.

Status: Released to Maven Central

Design

Xml schemas contain nearly everything we need for many web forms except for presentation information. Instead of seeking full separation of presentation from the data model (the xml schema) there are significant advantages in annotating the xsd itself according to a special schema to indicate presentation details. For one, refactoring is much easier without specialized IDE tooling that can read both our xsd and our presentation format.

Primary Use Case

As the submitted xml is compliant with a schema, the xml can be unmarshalled by a tool (see jaxb, scalaxb, xsd.exe into schema generated objects. Consequently any change in the schema will be reflected by compilation errors in the processing code if a statically typed language is used (such as Java, Scala, C#, etc.).

The features of javascript libraries like http://jquery.com mean that generating an html/javascript form that on submit posts xml that is compliant with the schema is a viable approach. The resultant css/html/javascript can be plugged in to any web server and presentation aspects can be overriden using annotations on the schema, css overrides and custom jquery script (the ability to separate script from structure is a nice feature of jquery in this instance).

Examples

Generated Form Annotated schema Comment
Demo form schema Feature showcase
Australian Census 2011 schema Based on the 2011 Australian Census form (pdf)
AMSA Pollution report schema pdf

Note. The examples work fine in the Chrome, Firefox and Internet Explorer 9 browsers (other browsers not tested yet). IE 9 will not display the above demos because they are sourced from htmlpreview.github.io which does not furnish the js with the appropriate mime-type. You can use the web service to display the demos succesfully for IE 9. IE is not being selenium tested yet but a SauceConnect job may be set up for that soon.

FAQ

I've already got a schema, can I generate a form from it?

Probably not! xsd-forms only supports a subset of xsd features. It was enough work for me to get this far, believe me! Supported features are documented in another section below. Your options are:

What xsd features are supported?

These xsd features are supported:

Bearing in mind the above restrictions, these features are supported:

How do I generate a form?

You need to make a schema using only the elements and types that are supported by xsd-forms. You can generate the form without adding any annotations at that point and it will use element names and such as defaults. A starter schema looks like this:

<xs:schema targetNamespace="http://org.moten.david/example"
  xmlns="http://org.moten.david/example" xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:i="http://moten.david.org/xsd-forms">
  <xs:annotation i:numberItems="true">
    <xs:appinfo>
      <i:header><![CDATA[
<h2>Title of the form</h2>
]]></i:header>
      <i:footer><![CDATA[
    <p>Thanks for your time.</p>
]]></i:footer>
      <i:extraImports><![CDATA[
    <!-- more imports here -->
]]></i:extraImports>
      <i:extraScript><![CDATA[
  // extra script would go here
]]></i:extraScript>
      <i:extraCss><![CDATA[
  /* extra css would go here */
]]></i:extraCss>
    </xs:appinfo>
  </xs:annotation>
  <xs:element name="name" type="xs:string">
    <xs:annotation i:label="Full name" />
  </xs:element>
</xs:schema>

Deploying this simple schema to the web service mentioned below gives you this form.

How do I annotate my schema?

Every element in your schema optionally can have a contained <xs:annotation/> element. Place attributes on that element from the xsd-forms schema like below:

annotations-demo.xsd ---> form

For a full list of annotations and their meanings see the top of the file annotation.scala.

This is what the form from annotations-demo.xsd looks like:

Generate using web service

A web service is available. At this service you can

Generate using a local web service

You need to have built everything once only:

mvn clean install

Then

cd xsd-forms-generator-webapp
mvn package jetty:run

Then go to http://localhost:8080 and fill in the form.

Generate using java/scala:

Add the following maven dependency to your pom.xml (you will need to have built the project from source so that the dependency is available in your local repository):

<dependency>
  <groupId>com.github.davidmoten.xsdforms</groupId>
  <artifactId>xsd-forms-generator</artifactId>
  <version>0.2.1</version>
</dependency>

and call

xsdForms.generateZip(..) 

or

xsdForms.generateHtml(...)

or

xsdForms.generateDirectory(...)

Generate using maven plugin

<plugin>
  <groupId>com.github.davidmoten.xsdforms</groupId>
  <artifactId>xsd-forms-maven-plugin</artifactId>
  <version>0.2.1</version>
  <executions>
    <execution>
      <goals>
        <goal>generate</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <!-- schema location can be on classpath or file system. Classpath is checked first -->
    <schema>/demo.xsd</schema>
  </configuration>
</plugin>

Here is a demonstration using xsd-forms-maven-plugin.

What do I need to do after I have designed a schema?

The default generated form just displays the captured xml on the page under the submit button. You will likely want to post the generated xml to a web server or perhaps email the xml to an address. To do that just set extraScript to the script below to override the submit behaviour:

//for example, display the xml in an alert box
processXml = function (xml) {
  alert(xml);
} 

Can I submit JSON instead?

Yep. Use this extraScript (using xml2json.js):

//for example, display json in an alert box
processXml = function (xml) {
  var result = toJson(xml);
  //alert or you could do a jquery ajax call to submit to a web server
  alert(result);
}

How do I override the appearance of the generated form?

Easy, just use javascript (jquery) in the extraScript. For instance, building on the above example:

//override the appearance of first input box
$('#item-6-instance-1_1_1').css("background", "aqua");

//override the default value of first input box
$('#item-6-instance-1_1_1').val("bingo");

An alternative is to put your own css overrides in xsd-forms-overrides.css.

How can I do my own thing with the xml?

Use this extraScript:

//override the processXml function
processXml = function(xml) {
  //do whatever you want here!!
};

How do I submit the xml/json to a web server?

Use this extraScript:

processXml = postXml('http://posttestserver456.com/post.php');

Or for more control use this extraScript and modify it:

//submit the xml to a web service using http post
processXml = function (xml) {
  var data = new Object();
  data.xml = xml;
  //disable submit button
  $('#submit').hide();
  $.ajax({
  type: 'POST',
  url: 'http://posttestserver456.com/post.php',
  data: data,
  success: 
    function (dat,textStatus,jqXHR) {
      $('#submit').hide();
    },
  error:
    function (jqXHR,textStatus,errorThrown) {
      alert(textStatus + '\n'+ errorThrown);
     $('#submit').show();
    },
  async:false
});
}

How do I pre-populate a form?

Schema default values will be set but if you want to for instance restore a form so a user can edit it then you need to write the necessary javascript as in the above examples. Using javascript/jquery you can call web services or extract parameters from the current url to populate the form.

Can I use the same schema for multiple different forms?

Yes. Just choose a different root element for each form.

Scope

The generated form should

Building

Technical overview

The use case is

Building from source

You need maven 3 installed and git binaries.

git clone https://github.com/davidmoten/xsd-forms.git
cd xsd-forms
mvn clean install

Running selenium tests

To run selenium tests (firefox, and chrome if setup):

mvn clean install -Dselenium=true

More options

Disable the chrome driver:

-Dchrome=false

Disable the firefox driver:

-Dfirefox=false

If you have the chromedriver executable installed ensure it is on the $PATH. For example, on linux

export PATH=/opt/chromedriver:$PATH

where /opt/chromedriver is the directory containing the chromedriver executable.

Viewing a sample form

cd xsd-forms-generator
mvn jetty:run

Then go to http://localhost:8080/demo-form.html.

Run the generator

cd xsd-forms-generator-webapp
mvn package jetty:run

Then go to http://localhost:8080/

Development plan