Here is the description of the content of the RNGtoHTMLform.xsl transformation.
The main RelaxNG markups are converted into XHTML markups and information about the XML structure is inserted into the form.
the generation of XML from the values entered in the form is further explained there.
Follow the steps
Generating web forms from XML specifications creates the bridge between data description and ways to create and modify data.
It also reduces the pain of writing and updating all the XHTML markups needed in a form.
Each input field of the generated XHTML form will have a "name" attribute containing
a XPath expression which designates the place of that value in the XML to generate.
Let us take an example with a piece of RelaxNG schema :
That specifies a XML like that one :
<rng:element name="root">
<rng:attribute name="att">
<rng:data type="string" />
</rng:attribute>
</rng:element>
The resulting XHTML form must be :
<root att="aString" />
In order to be able to generate valid XML from that form, we will set the attribute "name" of the input
tag to the XPath expression : "/root/@att". that means the value entered here will be the value
of the attribute "att" of the root markup "root". That gives that XHTML :
<label>att</label>
<input type="text" />
So, for each of the RelaxNG markup found in the schema, a behaviour is defined in the XSLT.
Those behaviours are explained below.
<label for="/root/@att">att</label>
<input type="text" name="/root/@att" />
RelaxNG markup behaviour / <form> grammar namespaces declaration :
<namespace prefix="" uri=""/>
... start initializes the variable pathInXml to '' ref go to its definition in schema or included schema(s) if not found include look to the definition in schema(s) included define continues browsing interleave continues browsing optional opens a <div class="optional"> anyName not supported zeroOrMore ou oneOrMore adds "+" and "-" buttons
opens a <div class="multiple">
adds "[]" to pathInXml element adds namespace prefix to the markup name
replaces previous "[]"(if exists) by a suffix "[1]"
adds the result to pathInXml (with "/" between)
if the following markup is text or data, adds a <label>
otherwise, opens a <p> list if followed by <zeroOrMore> or <oneOrMore> and then
<choice>, creates checkbox for each value otherwise continues browsing choice opens a <select> markup
if followed by value, adds an attribute sendselect="yes", the value selected will be sent to generate XML otherwise, adds an option for each ref or element found and a hidden div containing the content of that choice attribute adds "/@attributeName" to pathInXml
opens a <p> and adds a <label> text creates a <textarea> data type="boolean" creates two radio buttons "true" and "false" data type="anyURI" creates an <input type="file" /> data creates an <input type="text" /> documentation opens a <div class="documentation">
Problem is that firefox XSLT processor does not support XPath axis "namespace::". So it is not possible to retrieve in the XSLT transformation, the namespaces declared in the XML currently analyzed. In my case, that creates a problem when I attached their prefix to the names of the markups. In order to do that, I get the namespace of the markup defined in the schema and I browse the MAIN namespaces (declared in the main schema) in order to retrieve the corresponding prefix.
When the XSLT transformation is done by firefox XSLT processor, I can not have access to
that namespace declaration which could normally be stored in global variable "namespaces" that way :
What I do to work around that issue is that, before triggering the XSLT transformation, I parse the
XML document with javascript functions, and for each "xmlns:..." namespace declaration,
I add a special markup "nsp:namespace" under the "grammar" markup of the RelaxNG schema. The code for that is :
<xsl:variable name="namespaces" select="/rng:grammar/namespace::*"/>
So the resulting "nsp:namespace" markup has two attributes "prefix" and "uri".
Empty prefix is supported.
var grammarNode = xml.getElementsByTagNameNS("http://relaxng.org/ns/structure/1.0","grammar").item(0);
if (grammarNode) {
var grammarNodeAttrs = grammarNode.attributes;
for (var i = 0; i < grammarNodeAttrs.length; i++) {
if (grammarNodeAttrs[i].nodeName.match('xmlns')) {
var namespace = xml.createElementNS("namespace_declaration","nsp:namespace");
var prefix = grammarNodeAttrs[i].localName.replace(/^xmlns$/,"");
namespace.setAttribute("prefix",prefix);
namespace.setAttribute("uri",grammarNodeAttrs[i].value);
grammarNode.appendChild(namespace);
}
}
}
All those developments are released under Cecill licence.
The project Forms Generator is available on a svn, contact me for more information. In the future, a project might be created on sourceforge.
Projects svg 3d, XSD to RelaxNG converter, javascript SAX parser, javascript RelaxNG validator, javascript datatype library are published on Google code. Project javascript SAX parser is also published on Github.