Cogitech IncMiscellaneous | About us | Training | Tabular Topic Maps | Cogitative Topic Map Websites | Semantic Web Glasses | XWATL
Cogitative Technologies>XWATL

Secure SSL Certificates.

HTML Form Templates with XML

All in One and One for All

XSLT template library for WEB applications

SQL Table maintenance web based front-end with
Data-structure and business rules controlled by XML
Screen designs and database API controlled by XSL
Sitemap implemented as Xlink.

by , Cogitech, Inc.
nogievet@cogx.com
©Cogitech, Inc.



Front-end for table maintenance can include <insert>, <update>, <search>, <search result> and other action screens



All coding including site navigation, data updates and retrievals is implemented via XSLT transformations



XSLT stylesheets can be reused across all table maintenance web sites.
Development of a new web site is minimized to
Describe a table in XML.
Decide what action screens will be used.
Select XSLT stylesheets for action screens out of the pre-built stylesheet collection.
Add links for selected stylesheets into the XLink sitemap.



The provided solution is being used for maintanance of:
Lookup tables
General Ledger
Financial Adjustments
Table Driven Job Control Utility



Block Scheme of the chosen approach



3 Basic Elements:
TEXT: Generic Field

<!ELEMENT TEXTEMPTY>
<!ATTLIST TEXT
fieldCDATA#REQUIRED
defaultCDATA#IMPLIED
descrCDATA#IMPLIED
maskCDATA#IMPLIED
pk(true | false)false
qw(true | false)false
sizeCDATA#IMPLIED
>



SELECT: Field with a restricted value set

<!ELEMENT SELECT(OPTION+)>
<!ATTLIST SELECT
fieldCDATA#REQUIRED
defaultCDATA#IMPLIED
descrCDATA#IMPLIED
maskCDATA#IMPLIED
pk(true | false)false
qw(true | false)false
>

<!ELEMENT OPTIONEMPTY>
<!ATTLIST OPTION
valueCDATA#REQUIRED
textCDATA#REQUIRED
>



SYSTEM: Field values are determined automaticaly and can not be altered by users

<!ELEMENT SYSTEMEMPTY>
<!ATTLIST SYSTEM
fieldCDATA#REQUIRED
descrCDATA#IMPLIED
pk(true | false)false
qw(true | false)false
type(user_id | entry_date)#REQUIRED
>



XML fragment for a fictitious general ledger table:
<FORM> {...}
<FROM>gl</FROM>
<WHERE/>
<FIELDS>
<TEXTfield="gl_num"descr="general ledger number"default=""size="7"pk="true"qw="true"mask="\d{7}"/>
<SELECTfield="curr_code"descr="currency code"default="CND"pk="true"qw="true"mask="\w{3}">
<OPTIONvalue="AUD"text="Australian Dollar"/>
<OPTIONvalue="CND"text="Canadian Dollar"/>
<OPTIONvalue="USD"text="US Dollar"/>
<OPTIONvalue="RBL"text="Russian Ruble"/>
<OPTIONvalue="GBP"text="British Pound"/>
<OPTIONvalue="ILR"text="Italian Lira"/>
</SELECT>
<TEXTfield="ww_num"descr="world wide number"default=""size="5"mask="\d{3,}"/>
<TEXTfield="description"descr="gl description"default=""size="20"qw="true"/>
<SELECTfield="area"descr="financial area"default="1"mask=".+">
<OPTIONvalue="1"text="Asset & Liability"/>
<OPTIONvalue="2"text="Profit & Loss"/>
<OPTIONvalue="3"text="Off Balance Sheet"/>
</SELECT>
<SYSTEMfield="user_name"descr="user_id"type="user_id"qw="true"/>
<SYSTEMfield="entry_date"descr="entry date"type="entry_date"qw="true"/>
</FIELDS>
</FORM>



When information contained in XML is sufficient we will use XSLT stylesheets to transform XML to HTML and display result in the browser.



XSLT Script fragment for insert screen:
<TABLE>
<TR>
<TD>Field Name</TD>
<TD>Value</TD>
</TR>
<xslt:apply-templatesselect="./FIELDS/*"/>
</TABLE>
{...}
<xslt:templatematch="TEXT">
<TR>
<TD>
<xslt:attributename="onMouseOver">status='
<xslt:value-ofselect="@descr"/>
' </xslt:attribute>
<xslt:value-ofselect="@field"/>
</TD>
<TD>
<INPUTtype="TEXT">
<xslt:attributename="name">
<xslt:value-ofselect="@field"/>
</xslt:attribute>
<xslt:attributename="size">
<xslt:value-ofselect="@size"/>
</xslt:attribute>
<xslt:attributename="value">
<xslt:value-ofselect="@default"/>
</xslt:attribute>
</INPUT>
</TD>
</TR>
</xslt:template>
<xslt:templatematch="SELECT">
<TR>
<TD>
<xslt:attributename="onMouseOver">status='
<xslt:value-ofselect="@descr"/>
' </xslt:attribute>
<xslt:value-ofselect="@field"/>
</TD>
<TD>
<SELECT>
<xslt:attributename="name">
<xslt:value-ofselect="@field"/>
</xslt:attribute>
<OPTIONvalue=""selected="true">Select one</OPTION>
<xslt:apply-templatesselect="./OPTION"/>
</SELECT>
</TD>
</TR>
</xslt:template>
<xslt:templatematch="OPTION">
<OPTION>
<xslt:attributename="value">
<xslt:value-ofselect="@value"/>
</xslt:attribute>
<xslt:iftest="context()[@value $eq$ ancestor(SELECT)/@default]">
<xslt:attributename="SELECTED">true</xslt:attribute>
</xslt:if>
<xslt:value-ofselect="@text"/>
</OPTION>
</xslt:template>



Generated HTML:
<TABLE>
<TR>
<TD>Field Name</TD>
<TD>Value</TD>
</TR>
<TR>
<TDonMouseOver="status='general ledger number'">gl_num</TD>
<TD>
<INPUTtype="TEXT"name="gl_num"size="7"value=""/>
</TD>
</TR>
<TR>
<TD>curr_code</TD>
<TDonMouseOver="status='currency code'">
<SELECTname="curr_code">
<OPTIONvalue=""selected="true">Select one</OPTION>
<OPTIONvalue="AUD">Australian Dollar</OPTION>
<OPTIONvalue="CND">Canadian Dollar</OPTION>
<OPTIONvalue="USD">US Dollar</OPTION>
<OPTIONvalue="RBL">Russian Ruble</OPTION>
<OPTIONvalue="GBP">British Pound</OPTION>
<OPTIONvalue="ILR">Italian Lira</OPTION>
</SELECT>
</TD>
</TR>
<TR>
<TDonMouseOver="status='world wide number'">ww_num</TD>
<TD>
<INPUTtype="TEXT"name="ww_num"size="5"value=""/>
</TD>
</TR>
<TR>
<TDonMouseOver="status='gl description'">description</TD>
<TD>
<INPUTtype="TEXT"name="description"size="20"value=""/>
</TD>
</TR>
<TR>
<TD>area</TD>
<TDonMouseOver="status=' financial area '">
<SELECTname="area">
<OPTIONvalue=""selected="true">Select one</OPTION>
<OPTIONvalue="1"SELECTED="true">Asset & Liability</OPTION>
<OPTIONvalue="2">Profit & Loss</OPTION>
<OPTIONvalue="3">Off Balance Sheet</OPTION>
</SELECT>
</TD>
</TR>
</TABLE>



RDBMS data inquiries or updates
Transform XML to a server side JavaScript with integrated calls to database API and execute script via javascript:eval()



Combination of XSLT stylesheets and JavaScript works great
Code is surprisingly easy to read
XSL tags look like parameters in the script code (and parameters they are!)
1. create Java Script template in XSL
2. apply template to XML document to generate JavaScript in real time
XSLT transformations can be easily used to generate PYTHON, PERL or any other scripts as well



It is straightforward to convert XSLT that generates HTML:
<TABLE>
<TR>
<TD>Field Name</TD>
<TD>Value</TD>
</TR>
<xslt:apply-templatesselect="./FIELDS/*"/>
</TABLE>
Into a stylesheet fragment that generates JavaScript:
response.write('
<TABLE>'); response.write('
<TR>
<TD>Field Name</TD>
<TD>Value</TD>
</TR>
');
<xslt:apply-templatesselect="./FIELDS/*"/>
response.write('</TABLE>
');
response.write(" ... ") does not break well-formedness and can be freely integrated into XSLT.



XSLT template for SQL WHERE clause:
var where = " from <xslt:value-ofselect="FROM"></> where <xslt:value-ofselect="WHERE"></>";
<xslt:for-eachselect="FIELDS/(TEXT|SELECT)[@pk]">
where += ' and <xslt:value-ofselect="@field"></>=';
where +=dblq(Request('<xslt:value-ofselect="@field"></>'),'<xslt:value-ofselect="@qw"></>');
//dblq(a,b) - puts quotes around a if b is true
</>
where = where.replace(/where\s+and/g,"where"); //removes doublicate and
Generated JavaScript:
var where =" from gl where ";
where += ' and gl_num='+dbl_q(Request('gl_num'),'true');
where += ' and curr_code='+dbl_q(Request('curr_code'),'true');
where = where.replace(/where\s+and/g,"where");



XSLT template for SQL INSERT and SELECT clauses:
var insert='';
var list='';
<xslt:for-eachselect="FIELDS/(TEXT|SELECT)">
insert += dbl_q(Request('<xslt:value-ofselect="@field"></>'),'<xslt:value-ofselect="@qw"></>')+',';
list += '<xslt:value-ofselect="@field"></>,';
</>
<xslt:for-eachselect="FIELDS/SYSTEM[@type='entry_date']">
insert += 'GetDate(),';
list += '<xslt:value-ofselect="@field"></>,';
</>
<xslt:for-eachselect="FIELDS/SYSTEM[@type='user_id']">
insert += dblq(Request.ServerVariables('LOGON_USER'),'true')+',';
list += '<xslt:value-ofselect="@field"></>,';
</>
insert=insert.slice(0,-1);
list=list.slice(0,-1);
insert = 'insert <xslt:value-ofselect="FROM"></> ('+list+') values ('+ insert +')';
select = 'select '+list + where;



Generated JavaScript for SQL INSERT and SELECT clauses:
var insert = "";
var list = "";
insert += dbl_q(Request('gl_num'),'true')+',';
list += 'gl_num,';
insert += dbl_q(Request('curr_code'),'true')+',';
list += 'curr_code,';
insert += dbl_q(Request('ww_num'),'false')+',';
list += 'ww_num,';
insert += dbl_q(Request('description'),'true')+',';
list += 'description,';
insert += dbl_q(Request('area'),'false')+',';
list += 'area,';
list += 'user_name,';
update += 'user_name='+dbl_q(Request.ServerVariables('LOGON_USER'),'true')+',';
insert += 'GetDate(),';
list += 'entry_date,';
insert=insert.slice(0,-1);
list=list.slice(0,-1);
insert = 'insert gl ('+list+') values ('+ insert +')';
select = 'select '+list + where;



XSLT template for server side data validation:
<xslt:for-eachselect="FIELDS/(SELECT|TEXT)">
val= Request('<xslt:value-ofselect="@field"></>') + '';
<xslt:iftest="context()[@mask]">
if(val.match(/^<xslt:value-ofselect="@mask"></>$/) == null){
Response.write(
"<P>***<xslt:value-ofselect="@field"></> is invalid: " + val + "***</>");
status=-1;
}
</>
</>
if (status == -1) Response.end();



Generated Server side data validation JavaScript:
var val="";
var status=0;
val= Request('gl_num') + '';
if(val.match(/^\d{7}$/) == null){
Response.write("***gl_num is invalid: " + val + "***");
status=-1;
}
val= Request('curr_code') + '';
if(val.match(/^\w{3}$/) == null){
Response.write("***curr_code is invalid: " + val + "***");
status=-1;
}
val= Request('ww_num') + '';
if(val.match(/^\d{3,}$/) == null){
Response.write("***ww_num is invalid: " + val + "***");
status=-1;
}
val= Request('description') + '';
val= Request('area') + '';
if(val.match(/^.+$/) == null){
Response.write("***area is invalid: " + val + "***");
status=-1;
}
if (status == -1) Response.end();



XLink Sitemaps

A typical sitemap (Entry/Search/Insert/Update):
Role of Commit screens in this context is to build and execute SQL action queries such as update, insert or delete and inquire user for final OK. Back links and rollbacks are not shown.



For some applications we need ability to clone records.(Entry/Search/Insert/Clone/Update)



For some applications insert and search screens should be united into one entry screen (Entry+Insert/Search/Clone/Update)



Problem:
Links hardcoded in stylesheets leave the headache of maintaining link integrity
Change, add or removal of one action screen forces changes in all other screens thus killing the sole idea of completely reusable XSLT scripts.
Solution:
Move link inter-dependency into a central sitemap
Use XLink vocabulary and add an extended XLink element xitemap to the main XML DTD

<!ELEMENT xitemap(LOCATOR+|ARC*)>
<!ATTLIST xitemap
xmlns:xlinkCDATA#FIXEDhttp://www.w3.org/XML/XLink/0.9
xlink:type(simple|extended|locator|arc)#FIXEDextended
>



Locators define locations of stylesheets for action screens

<!ELEMENT locatorEMPTY>
<!ATTLIST locator
xlink:type(simple|extended|locator|arc)#FIXEDlocator
xlink:show(new|parsed|replace)#FIXEDparsed
xlink:actuate(user|auto)#FIXEDuser
xlink:hrefCDATA#REQUIRED
xlink:idID#REQUIRED
xlink:titleCDATA#IMPLIED
restype(js|html)#REQUIRED
>
Attribute restype represents MIME type of the transformed document.
html stands for text/html. Transformed document is sent directly to client.
js stands for application/x-javascript. Transformed document is executed on the server.



Arcs define traversal behavior between screens

<!ELEMENT arcEMPTY>
<!ATTLIST arc
xlink:type(simple|extended|locator|arc)#FIXEDarc
xlink:fromIDREF#REQUIRED
xlink:toIDREF#REQUIRED
userdefault(true|false)false
>
Attribute userdefault is used to specify default link.



Xlink sitemap for the web site shown on Slide 24:
<FORMcurrentrole="entry"title="General Ledger Maintenance">
<xitemap>
<locatorxlink:id="search"xlink:href="sql.xsl"restype="js"xlink:title="Search Results"/>
<locatorxlink:id="entry"xlink:href="form.xsl"restype="html"xlink:title="Entry Screen"/>
<locatorxlink:id="edit"xlink:href="edit.xsl"restype=" JavaScript "xlink:title="Edit Screen"/>
<locatorxlink:id="update"xlink:href="commit.xsl"restype="js"xlink:title="Update Commit"/>
<locatorxlink:id="insert"xlink:href="commit.xsl"restype=" js"xlink:title="Insert Commit"/>
<arcfrom="entry"to="search"userdefault="true"/>
<arcfrom="entry"to="insert"/>
<arcfrom="search"to="entry"/>
<arcfrom="search"to="edit"/>
<arcfrom="search"to="insert"/>
<arcfrom="edit"to="entry"/>
<arcfrom="edit"to="update"userdefault="true"/>
<arcfrom="update"to="entry"userdefault="true"/>
<arcfrom="insert"to="entry"/>
</xitemap>
<FIELDS>{...}</FIELDS>
</FORM>



Generic XSLT template used in stylesheets to transform Xlink fragment into a set of submit buttons:
<xslt:for-eachselect="/FORM/xitemap/arc[@from $eq$ /FORM/@currentrole]">
<INPUTtype="SUBMIT"name="role">
<xslt:attributename="value">
<xslt:value-ofselect="@to"/>
</xslt:attribute>
</INPUT>
</xslt:for-each>
Generated HTML when [FORM/@currentrole="entry"]:
<INPUTname="role"type="SUBMIT"value="search"/>
<INPUTname="role"type="SUBMIT"value="insert"/>



XSLT template that generates set of buttons and a submit button for the default arc:
<xslt:for-eachselect="/FORM/xitemap/arc[@from $eq$ /FORM/@role]">
<INPUT>
<xslt:attributename="value">
<xslt:value-ofselect="@to"/>
</xslt:attribute>
<xslt:attributename="type">
<xslt:choose>
<xslt:whentest="@userdefault">SUBMIT</xslt:when>
<xslt:otherwise>BUTTON</xslt:otherwise>
</xslt:choose>
</xslt:attribute>
<xslt:attributename="onclick"> this.form.role.value='
<xslt:value-ofselect="@to"/>
';this.form.submit(); </xslt:attribute>
</INPUT>
</xslt:for-each>
<INPUTtype="hidden"name="role"value=""/>
Generated HTML when [FORM/@currentrole="search"]:
<INPUTtype="SUBMIT"value="search"onclick="this.form.role.value='search' ;this.form.submit();"/>
<INPUTtype="BUTTON"value="insert"onclick="this.form.role.value='insert' ;this.form.submit();"/>
<INPUTtype="hidden"name="role"value=""/>



When a Link is traversed it sends the role parameter in the header. Server side wrapper script interprets this parameter and:
Changes currentrole attribute on the root FORM element of the XML file
Retrieves locator with xlink:id corresponding to the currentrole parameter
Changes html:TITLE according to xlink:title of the locator
From xlink:href attribute determines stylesheet to use and transforms XML
Depending on the value of resultType attribute
If html - sends result directly to the browser
If js - executes result via javascript:eval()



Server side wrapper script written in JavaScript for ASP. MSXML is used as the server side DOM processor.
var role = ''+Request.Form("role");
var formRoot=formDoc.documentElement;
if (role != 'undefined' )
formRoot.setAttribute("currentrole", role);
else
role=formRoot.getAttribute("currentrole"); //get default
var styleLocator=formRoot.selectSingleNode('xitemap/locator[@id="' + role + '"]');
//{...} handle Error if Syle not set for role
var style=styleLocator.getAttribute("href");
//{...} set html:TITLE depending on styleLocator.getAttribute("title")
var formStyle=CreateXMLDOM(style) // load or get stylesheet
try {
var result = formDoc.transformNode(formStyle);
result = result.replace(/&lt;/g,"<");
result = result.replace(/&gt;/g,">");
result = result.replace(/&amp;/g,'&');
}
catch (exception) {
result = reportRuntimeError(exception);
}
//Determine type of the transformed document and either display it or execute.
var resultType =styleLocator.getAttribute("resultType");
switch(resultType){ // behavior in old Xlink
case "html":
Response.write(result);
break;
case "js":
eval(result);
break;
}



Getting valid JavaScript from valid XML:
Both ends of XSLT transformation must be well-formed XML tries.
Text string is a well-formed XML if it does not have illegal characters.
To make JavaScript templates well formed, use character entities &amp;, &gt;, &lt; in place of &, >, <
After the transformation, use Regular Expressions methods to make a valid JavaScript.



Using XSLT template library for database access applications features
Separation of data structure and business rules in XML from database API and presentation in XSLT.
Facilitated centralized sitemap maintenance.
Modular, low development costs due to reusing pre-built stylesheets.
Reduced number of database calls due to shifting table structure and business rules to XML.
XML based: easy integration with other systems.
Extensible: adding features or business rules is easy.
Client requirments: any HTML4 aware browser.
Simplified user training and client installation.
Updated version of this presentation is available at http://www.cogx.com/xtm



Further Improvements

To modularize approach even further
- Store named attributes in a reusable template collection
- Use xslt:import element to import template collection
- Refer to the pre-built templates using xsl:call-template element
<xslt:call-templatename="BuildWhereClause"></>
<xslt:call-templatename="DrawLinksAsButtons"></>
<xslt:call-templatename="DrawLinksAsImages"></>



References

XSL Transformations (XSLT) Working Draft 9 July 1999 http://www.w3.org/1999/07/WD-xslt-19990709
XML Path Language (XPath) Working Draft 9 July 1999 http://www.w3.org/1999/07/WD-xpath-19990709
W3C XML Linking Language Working Draft http://www.w3.org/1999/07/WD-xlink-19990726
XML XLink Requirements http://www.w3.org/TR/1999/NOTE-xlink-req-19990224
XML Linking Language (XLink) Design Principles http://www.w3.org/TR/1998/NOTE-xlink-principles-19980303
XML at Microsoft http://msdn.microsoft.com/xml/c-frame.htm#/xml/default.asp
XSL-List Archive http://www.mulberrytech.com/xsl/xsl-list/archive/
XML-DEV Archive http://www.lists.ic.ac.uk/hypermail/xml-dev/
St. Laurent Open-source XLink library http://www.simonstl.com/projects/xlinkfilter/index.html
XT Version 19990725 http://www.jclark.com/xml/xt.html
Cafe con Leche http://www.metalab.unc.edu/xml
The SGML/XML Web Page by Robin Coverhttp://www.oasis-open.org/cover/





Budget Web Hosting and Cheap Domain Name Registration

Cogitech Inc. Made with Bexcelor & Tabular Topic Maps