<?xml version='1.0'?>
<!-- NOTE: this XSLT transforms a XForms simple syntax into an
XML Schema conforming to the October 24, 2000 candidate
recomendation -->
<xsl:transform version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsd="http://www.w3.org/2000/10/XMLSchema"
xmlns="http://www.w3.org/2000/10/XMLSchema"
xmlns:xfm="http://www.w3.org/2000/12/xforms" >
<xsl:strip-space elements="xform"/>
<xsl:output method="xml" indent="yes" encoding="UTF-8"
standalone="no" />
<!-- the special indicator used for maxOccurs to mean unbounded -->
<xsl:variable name="maxOccursSpecial">*</xsl:variable>
<!-- the special value used for maxLength to mean unbounded -->
<xsl:variable name="maxLengthSpecial">unlimited</xsl:variable>
<!-- the special value used for min to mean minus infinity -->
<xsl:variable name="minInfinity">minus infinity</xsl:variable>
<!-- the special value used for max to mean plus infinity -->
<xsl:variable name="maxInfinity">plus infinity</xsl:variable>
<!-- the special value used for scale to mean unlimited decimals -->
<xsl:variable name="unlimitedScale">unlimited</xsl:variable>
<!-- the special value used for precision to mean unlimited precision -->
<xsl:variable name="unlimitedPrecision">unlimited</xsl:variable>
<!-- the list of WML classes -->
<xsl:variable name="classesList" >AaNnXxMm</xsl:variable>
<xsl:variable name="classesTrans">01234567</xsl:variable>
<!-- special characters to escape in patterns -->
<xsl:variable name="specialCharacters">\|.-^?*+{}()[]</xsl:variable>
<!-- template: match="/"
function: matches the root node, calls the template "xform" for
all <xform> elements. drops any other elements.
parameters: none
output: <schema> skeleton.
-->
<xsl:template match="/">
<xsl:element name="xsd:schema">
<xsl:element name="xsd:annotation">
<xsl:element name="xsd:documentation">
<xsl:text>Automatically generated from an XForms data model.</xsl:text>
<xsl:text>Using</xsl:text>
<xsl:value-of select="system-property('xsl:vendor')"/>
<xsl:text>at XSL version</xsl:text>
<xsl:value-of select="format-number(system-property('xsl:version'),
'#0.0')"/>.
<xsl:if test="system-property('xsl:version') > 1.0">
Note, the stylesheet was designed for a XSLT version 1.0 processor.
</xsl:if>
</xsl:element>
</xsl:element>
<!-- output the xform -->
<xsl:apply-templates />
</xsl:element>
</xsl:template>
<!--
xform element
-->
<!-- template: match="xform"
function: matches an xform, calls the templates for all childs
parameters: none
output: none of it's own
-->
<xsl:template match="xform">
<!-- output the elements -->
<xsl:apply-templates />
</xsl:template>
<!--
model element
-->
<!-- template: match="model"
function: matches an xform, calls the templates for all childs
parameters: none
output: none of it's own
-->
<xsl:template match="model">
<!-- output the elements -->
<xsl:apply-templates />
</xsl:template>
<!--
schema element
-->
<!-- template: match="schema"
function: matches an schema, and copies the inlined schema definition
to the result tree
parameters: none
output: copy of the input
-->
<xsl:template match="xsd:schema">
<!-- copy XML Schema definition -->
<xsl:copy-of select="node()"/>
</xsl:template>
<!--
simple element
-->
<!-- template: match="simple"
function: matches an simple, and processes the child elements
parameters: none
output: none of its own
-->
<xsl:template match="simple">
<!-- output the elements -->
<xsl:apply-templates />
</xsl:template>
<!--
isntance element
-->
<!-- template: match="instance"
function: filters the instance
parameters: none
output: none
-->
<xsl:template match="instance"/>
<
binding element
-->
<!-- template: match="binding"
function: filters the binding
parameters: none
output: none
-->
<xsl:template match="binding"/>
<!--
submit element
-->
<!-- template: match="submit"
function: filters the submit elements
parameters: none
output: none
-->
<xsl:template match="submit"/>
<!--
group element
-->
<!-- template: matches="group"
function: converts the group into a complex type and processes
all childs
parameters: none
output: a complex type representing the group
-->
<xsl:template match="group">
<xsl:element name="xsd:element">
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<!-- check attributes -->
<xsl:call-template name="checkAttributes"/>
<xsl:element name="xsd:complexType">
<xsl:element name="xsd:complexContent">
<xsl:element name="xsd:extension">
<!-- check for a base -->
<xsl:attribute name="base">xsd:anyType</xsl:attribute>
<!-- the rest of the elements are always a sequence -->
<xsl:element name="xsd:sequence">
<!-- include all chile elements -->
<xsl:apply-templates/>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:template>
<!--
union element
-->
<!-- template: matches="union"
function: converts a union into a union of simpleTypes.
parameters: none
output: converted definition
-->
<xsl:template match="union">
<xsl:choose>
<xsl:when test="string-length(@name)=0">
<xsl:message terminate="no">
An anonymous union definition is not supported.
</xsl:message>
<xsl:comment> Anonymous union definition dropped </xsl:comment>
</xsl:when>
<xsl:otherwise>
<xsl:element name="xsd:element">
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<!-- check common attributes -->
<xsl:call-template name="checkAttributes"/>
<xsl:element name="xsd:simpleType">
<xsl:element name="xsd:union">
<xsl:apply-templates />
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!--
switch element
-->
<!-- template: matches="switch"
function: converts the switch into a choice and processes all
cases
parameters: none
output: a choice representing the variant
-->
<xsl:template match="switch">
<xsl:choose>
<xsl:when test="string-length(@name)=0">
<xsl:message terminate="no">
An anonymous variant definition is not supported.
</xsl:message>
<xsl:comment> Anonymous variant definition dropped </xsl:comment>
</xsl:when>
<xsl:otherwise>
<xsl:element name="xsd:element">
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<!-- check common attributes -->
<xsl:call-template name="checkAttributes"/>
<xsl:element name="xsd:complexType">
<xsl:element name="xsd:complexContent">
<xsl:element name="xsd:extension">
<xsl:attribute name="base">xsd:anyType</xsl:attribute>
<xsl:element name="xsd:choice">
<xsl:apply-templates select="case"/>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!--
case element
-->
<!-- template: matches="caase"
function: converts the case into a sequence of other elements
parameters: none
output: a sequence representing the case
-->
<xsl:template match="case">
<xsl:element name="xsd:sequence">
<xsl:if test="string-length(@name) > 0">
<xsl:attribute name="xfm:name">
<xsl:value-of select="@name"/>
</xsl:attribute>
</xsl:if>
<xsl:if test="string-length(@condition) > 0">
<xsl:attribute name="xfm:condition">
<xsl:value-of select="@condition"/>
</xsl:attribute>
</xsl:if>
<!-- include elements -->
<xsl:apply-templates />
</xsl:element>
</xsl:template>
<!--
string element
-->
<!-- template: matches="string"
function: converts a string.
parameters: none
output: converted definition
note: it is assumed that all value childs
conform to all other restrictions, otherwise their
value will be allowed despide the further
restrictions.
-->
<xsl:template match="string">
<!-- create definition -->
<xsl:variable name="definition">
<xsl:element name="xsd:simpleType">
<xsl:choose>
<!-- if we have a closed range, or no enumeration value, we can
create a simple type -->
<xsl:when test="@enum='closed' or
count(value)=0">
<xsl:element name="xsd:restriction">
<xsl:attribute name="base">xsd:string</xsl:attribute>
<xsl:call-template name="restrictString"/>
<xsl:apply-templates select="value"/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:element name="xsd:union">
<xsl:element name="xsd:simpleType">
<xsl:element name="xsd:restriction">
<xsl:attribute name="base">xsd:string</xsl:attribute>
<xsl:call-template name="restrictString"/>
<xsl:apply-templates select="value"/>
</xsl:element>
</xsl:element>
<xsl:element name="xsd:simpleType">
<xsl:element name="xsd:restriction">
<xsl:attribute name="base">xsd:string</xsl:attribute>
<xsl:call-template name="restrictString"/>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:variable>
<!-- if we have a name, we can create an element or attribute,
otherwise we're part of a union -->
<xsl:choose>
<xsl:when test="string-length(@name) > 0">
<!-- create element or attribute -->
<xsl:element name="xsd:element">
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<!-- check common attributes -->
<xsl:call-template name="checkAttributes"/>
<xsl:choose>
<!-- if we have no children, and no other restrictions,
we can make a short definition -->
<xsl:when test='count(child::node())=0 and @minLength="0" and
@maxLength="unlimited" and
string-length(@pattern)=0 and
string-length(@mask)=0'>
<xsl:attribute name="type">xsd:string</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<!-- dump full definition -->
<xsl:copy-of select="$definition"/>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<!-- just dumpe definition -->
<xsl:copy-of select="$definition"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- template: name="restrictString"
function: add erstrictions to a string
parameters: a string context node with the following attributes
@maxLength
@minLength
@mask
@pattern
and the following child elements
<pattern/>
<mask/>
output: elements to represent the restrictions
-->
<xsl:template name="restrictString">
<!-- create pattern -->
<xsl:variable name="pattern">
<xsl:for-each select="mask|pattern">
<xsl:text>(</xsl:text>
<xsl:choose>
<xsl:when test='name()="mask"'>
<xsl:call-template name="make-pattern">
<xsl:with-param name="mask">
<xsl:value-of select="."/>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
<xsl:text>)</xsl:text>
<xsl:if test="not(position()=last())">
<xsl:text>|</xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:if test="@mask">
<xsl:if test="count(mask|pattern) > 0">
<xsl:text>|</xsl:text>
</xsl:if>
<xsl:text>(</xsl:text>
<xsl:call-template name="make-pattern">
<xsl:with-param name="mask">
<xsl:value-of select="@mask"/>
</xsl:with-param>
</xsl:call-template>
<xsl:text>)</xsl:text>
</xsl:if>
<xsl:if test="@pattern">
<xsl:if test="string-length(@mask) > 0 and
count(mask|pattern) > 0">
<xsl:text>|</xsl:text>
</xsl:if>
<xsl:text>(</xsl:text>
<xsl:value-of select="@pattern"/>
<xsl:text>)</xsl:text>
</xsl:if>
</xsl:variable>
<!-- check if @length is an non negative integer -->
<xsl:variable name="lengthIsNNI">
<xsl:call-template name="checkNonNegInt">
<xsl:with-param name="test">
<xsl:value-of select="@length"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<!-- check if @max is an non negative integer -->
<xsl:variable name="maxIsNNI">
<xsl:call-template name="checkNonNegInt">
<xsl:with-param name="test">
<xsl:value-of select="@max"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<!-- check if @min as an non negative integer -->
<xsl:variable name="minIsNNI">
<xsl:call-template name="checkNonNegInt">
<xsl:with-param name="test">
<xsl:value-of select="@min"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<!-- write xfm:length restriction -->
<xsl:if test="string-length(@length) > 0 and
not(@length=$maxLengthSpecial) and
$lengthIsNNI='false'">
<xsl:attribute name="xfm:length">
<xsl:value-of select="@length"/>
</xsl:attribute>
</xsl:if>
<!-- write xfm:maxLength restriction -->
<xsl:if test="string-length(@max) > 0 and
not(@max=$maxLengthSpecial) and
$maxIsNNI='false'">
<xsl:attribute name="xfm:maxLength">
<xsl:value-of select="@max"/>
</xsl:attribute>
</xsl:if>
<!-- write xfm:minLength restriction -->
<xsl:if test="string-length(@min) > 0 and
not(@min='0') and
$minIsNNI='false'">
<xsl:attribute name="xfm:minLength">
<xsl:value-of select="@min"/>
</xsl:attribute>
</xsl:if>
<!-- write xsd:length restriction -->
<xsl:choose>
<xsl:when test="$lengthIsNNI='true'">
<xsl:if test="not(@length=$maxLengthSpecial)">
<xsl:element name="xsd:length">
<xsl:attribute name="value">
<xsl:value-of select="@length"/>
</xsl:attribute>
</xsl:element>
</xsl:if>
</xsl:when>
<xsl:when test="count(length) > 0">
<xsl:element name="xsd:length">
<xsl:attribute name="value">
<xsl:value-of select="length[1]"/>
</xsl:attribute>
</xsl:element>
</xsl:when>
</xsl:choose>
<!-- write xsd:maxLength restriction -->
<xsl:choose>
<xsl:when test="$maxIsNNI='true'">
<xsl:if test="not(@max=$maxLengthSpecial)">
<xsl:element name="xsd:maxLength">
<xsl:attribute name="value">
<xsl:value-of select="@max"/>
</xsl:attribute>
</xsl:element>
</xsl:if>
</xsl:when>
<xsl:when test="count(max) > 0">
<xsl:element name="xsd:maxLength">
<xsl:attribute name="value">
<xsl:value-of select="max[1]"/>
</xsl:attribute>
</xsl:element>
</xsl:when>
</xsl:choose>
<!-- write xsd:minLength restriction -->
<xsl:choose>
<xsl:when test="$minIsNNI='true'">
<xsl:if test="not(@min='0')">
<xsl:element name="xsd:minLength">
<xsl:attribute name="value">
<xsl:value-of select="@min"/>
</xsl:attribute>
</xsl:element>
</xsl:if>
</xsl:when>
<xsl:when test="count(min) > 0">
<xsl:element name="xsd:min">
<xsl:attribute name="value">
<xsl:value-of select="min[1]"/>
</xsl:attribute>
</xsl:element>
</xsl:when>
</xsl:choose>
<!-- write xsd:pattern -->
<xsl:if test="string-length($pattern) > 0">
<xsl:element name="xsd:pattern">
<xsl:attribute name="value">
<xsl:value-of select="$pattern"/>
</xsl:attribute>
</xsl:element>
</xsl:if>
</xsl:template>
<!-- template: name="make-pattern"
function: converts a mask to a pattern
parameters: mask : the mask to transform
i : current position inside mask
last : last source character
count : how many times did the last character
occur
output: a pattern with the same meaning
-->
<xsl:template name="make-pattern">
<xsl:param name="mask"/>
<xsl:param name="i">0</xsl:param>
<xsl:param name="last"/>
<xsl:param name="count"/>
<xsl:choose>
<!-- if there are characters to process, do so -->
<xsl:when test="$i < string-length($mask)">
<!-- get current character -->
<xsl:variable name="c">
<xsl:value-of select="substring($mask, $i + 1, 1)"/>
</xsl:variable>
<!-- process it -->
<xsl:choose>
<!-- check for special characters first -->
<!-- the backslash (\): the next character is ment literally -->
<xsl:when test="$c='\'">
<!-- output old count -->
<xsl:if test="$count > 1">
<xsl:text>{</xsl:text>
<xsl:value-of select="$count"/>
<xsl:text>}</xsl:text>
</xsl:if>
<!-- check if the character has to be escaped -->
<xsl:call-template name="escape-char">
<xsl:with-param name="char">
<xsl:value-of select="substring($mask, $i + 2, 1)"/>
</xsl:with-param>
</xsl:call-template>
<!-- call recursively -->
<xsl:call-template name="make-pattern">
<xsl:with-param name="mask">
<xsl:value-of select="$mask"/>
</xsl:with-param>
<xsl:with-param name="i">
<xsl:value-of select="$i + 2"/>
</xsl:with-param>
<xsl:with-param name="last">
<xsl:text>\</xsl:text>
</xsl:with-param>
<xsl:with-param name="count">
<xsl:value-of select="0"/>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<!-- the asterix (*): any other number of the following class -->
<xsl:when test="$c='*'">
<!-- get next character -->
<xsl:variable name="next">
<xsl:value-of select="substring($mask, $i + 2, 1)"/>
</xsl:variable>
<xsl:choose>
<!-- it the next is equal to the last, create special output -->
<xsl:when test="$last=$next">
<xsl:text>{</xsl:text>
<xsl:value-of select="$count"/>
<xsl:text>,}</xsl:text>
</xsl:when>
<xsl:otherwise>
<!-- output old count -->
<xsl:if test="$count > 1">
<xsl:text>{</xsl:text>
<xsl:value-of select="$count"/>
<xsl:text>}</xsl:text>
</xsl:if>
<!-- converte wml character class into unicode class -->
<xsl:call-template name="convert-characterClass">
<xsl:with-param name="class">
<xsl:value-of select="$next"/>
</xsl:with-param>
</xsl:call-template>
<xsl:text>*</xsl:text>
</xsl:otherwise>
</xsl:choose>
<!-- keep in mind, that any mask ends after a *. -->
</xsl:when>
<!-- a number [1-9]: repeat next character n times -->
<xsl:when test="contains('0123456789', $c)">
<!-- get next character -->
<xsl:variable name="next">
<xsl:value-of select="substring($mask, $i + 2, 1)"/>
</xsl:variable>
<xsl:choose>
<!-- when the next character equals the last,
just increase count -->
<xsl:when test="$last=$next">
<xsl:call-template name="make-pattern">
<xsl:with-param name="mask">
<xsl:value-of select="$mask"/>
</xsl:with-param>
<xsl:with-param name="i">
<xsl:value-of select="$i + 2"/>
</xsl:with-param>
<xsl:with-param name="last">
<xsl:value-of select="$last"/>
</xsl:with-param>
<xsl:with-param name="count">
<xsl:value-of select="$count + $c"/>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<!-- output old count -->
<xsl:if test="$count > 1">
<xsl:text>{</xsl:text>
<xsl:value-of select="$count"/>
<xsl:text>}</xsl:text>
</xsl:if>
<!-- convert character class -->
<xsl:variable name="out">
<xsl:call-template name="convert-characterClass">
<xsl:with-param name="class">
<xsl:value-of select="$next"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<!-- output unicode character classes -->
<xsl:value-of select="$out"/>
<!-- call recursively -->
<xsl:call-template name="make-pattern">
<xsl:with-param name="mask">
<xsl:value-of select="$mask"/>
</xsl:with-param>
<xsl:with-param name="i">
<xsl:value-of select="$i + 2"/>
</xsl:with-param>
<xsl:with-param name="last">
<xsl:value-of select="$next"/>
</xsl:with-param>
<xsl:with-param name="count">
<xsl:value-of select="$c"/>
</xsl:with-param>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<!-- if it's the same as the last, just increase count -->
<xsl:when test='$c=$last'>
<!-- call recursively -->
<xsl:call-template name="make-pattern">
<xsl:with-param name="mask">
<xsl:value-of select="$mask"/>
</xsl:with-param>
<xsl:with-param name="i">
<xsl:value-of select="$i + 1"/>
</xsl:with-param>
<xsl:with-param name="last">
<xsl:value-of select="$last"/>
</xsl:with-param>
<xsl:with-param name="count">
<xsl:value-of select="$count + 1"/>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<!-- a new/different character -->
<xsl:otherwise>
<!-- catches the fact that the user missed the backslash in
front of a literal character -->
<!-- output old count -->
<xsl:if test="$count > 1">
<xsl:text>{</xsl:text>
<xsl:value-of select="$count"/>
<xsl:text>}</xsl:text>
</xsl:if>
<!-- convert character class -->
<xsl:variable name="out">
<xsl:call-template name="convert-characterClass">
<xsl:with-param name="class">
<xsl:value-of select="$c"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<!-- output unicode character classes -->
<xsl:value-of select="$out"/>
<!-- call recursively -->
<xsl:call-template name="make-pattern">
<xsl:with-param name="mask">
<xsl:value-of select="$mask"/>
</xsl:with-param>
<xsl:with-param name="i">
<xsl:value-of select="$i + 1"/>
</xsl:with-param>
<xsl:with-param name="last">
<xsl:value-of select="$c"/>
</xsl:with-param>
<xsl:with-param name="count">
<xsl:value-of select="1"/>
</xsl:with-param>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:if test="$count > 1">
<xsl:text>{</xsl:text>
<xsl:value-of select="$count"/>
<xsl:text>}</xsl:text>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- template: name="convert-characterClass"
function: converts a wml character class into the proper
unicode character classes, as defined by <characterClasses/>
parameter: class :wml character class
output: matching unicode class(es)
-->
<xsl:template name="convert-characterClass">
<xsl:param name="class"/>
<xsl:if test='contains($classesList, $class)'>
<xsl:variable name="i">
<xsl:value-of select="translate($class, $classesList, $classesTrans)"/>
</xsl:variable>
<xsl:value-of select="document('')//this:class[$i + 1]/this:unicode"/>
</xsl:if>
</xsl:template>
<!-- template: name="escape-char"
function: escapes characters, to not have a special meaning in
reg exp
parameters: char :character to escape
output: save version
-->
<xsl:template name="escape-char">
<xsl:param name="char"/>
<xsl:choose>
<!-- check if the character must be escaped -->
<xsl:when test='contains($specialCharacters, $char)'>
<xsl:text>\</xsl:text>
<xsl:value-of select="$char"/>
</xsl:when>
<xsl:otherwise>
<!-- no escaping needed, just return $char -->
<xsl:value-of select="$char"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!--
boolean element
-->
<!-- template: match="boolean"
function: converts a boolean into a xsd:boolean
parameters: none
output: converted definition
-->
<xsl:template match="boolean">
<!-- create definition -->
<xsl:variable name="definition">
<xsl:element name="xsd:simpleType">
<xsl:choose>
<!-- if we have closed range, or no enumeration value, we can
create simple type -->
<xsl:when test="@enum='closed' or
count(value)=0">
<xsl:element name="xsd:restriction">
<xsl:attribute name="base">xsd:boolean</xsl:attribute>
<xsl:apply-templates select="value"/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:element name="xsd:union">
<xsl:element name="xsd:simpleType">
<xsl:element name="xsd:restriction">
<xsl:attribute name="base">xsd:boolean</xsl:attribute>
<xsl:apply-templates select="value"/>
</xsl:element>
</xsl:element>
<xsl:element name="xsd:simpleType">
<xsl:element name="xsd:restriction">
<xsl:attribute name="base">xsd:boolean</xsl:attribute>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:variable>
<!-- if we have a name, we can create an element or attribute,
otherwise we're part of a union -->
<xsl:choose>
<xsl:when test="string-length(@name) > 0">
<!-- create element or attribute -->
<xsl:element name="xsd:element">
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<!-- check common attributes -->
<xsl:call-template name="checkAttributes"/>
<xsl:choose>
<!-- if we have no children, and no other restrictions,
we can make a short definition -->
<xsl:when test='count(child::node())=0'>
<xsl:attribute name="type">xsd:boolean</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<!-- dump full definition -->
<xsl:copy-of select="$definition"/>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<!-- just dumpe definition -->
<xsl:copy-of select="$definition"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!--
number element
-->
<!-- template: matches="number"
function: converts a number into an xsd:number.
parameters: none
output: converted definition
-->
<xsl:template match="number">
<!-- create definition -->
<xsl:variable name="definition">
<xsl:element name="xsd:simpleType">
<xsl:choose>
<!-- if we have closed range, or no enumeration value, we can
create simple type -->
<xsl:when test="@enum='closed' or
count(value)=0">
<xsl:element name="xsd:restriction">
<xsl:attribute name="base">xsd:decimal</xsl:attribute>
<xsl:call-template name="restrictNumber"/>
<xsl:apply-templates select="value"/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:element name="xsd:union">
<xsl:element name="xsd:simpleType">
<xsl:element name="xsd:restriction">
<xsl:attribute name="base">xsd:decimal</xsl:attribute>
<xsl:call-template name="restrictNumber"/>
<xsl:apply-templates select="value"/>
</xsl:element>
</xsl:element>
<xsl:element name="xsd:simpleType">
<xsl:element name="xsd:restriction">
<xsl:attribute name="base">xsd:decimal</xsl:attribute>
<xsl:call-template name="restrictNumber"/>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:variable>
<!-- if we have a name, we can create an element or attribute,
otherwise we're part of a union -->
<xsl:choose>
<xsl:when test="string-length(@name) > 0">
<!-- create element or attribute -->
<xsl:element name="xsd:element">
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<!-- check common attributes -->
<xsl:call-template name="checkAttributes"/>
<xsl:choose>
<!-- if we have no children, and no other restrictions,
we can make a short definition -->
<xsl:when test='count(child::node())=0 and
(string-length(@min)=0 or @min=$minInfinity) and
(string-length(@max)=0 or @max=$maxInfinity) and
(string-length(@precision)=0 or
@precision=$unlimitedPrecision) and
(string-length(@scale)=0 or @scale=$unlimitedScale)'>
<xsl:attribute name="type">xsd:decimal</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<!-- dump full definition -->
<xsl:copy-of select="$definition"/>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<!-- just dumpe definition -->
<xsl:copy-of select="$definition"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- template: name="restrictNumber"
function: add erstrictions to a number
parameters: a number context node with the following attributes
@max
@min
@precision
@scale
and the following child elements
<min>
<max>
<precision>
<scale>
output: elements to represent the restrictions
-->
<xsl:template name="restrictNumber">
<xsl:message terminate="no">@max:<xsl:value-of select="@max"/></xsl:message>
<!-- check if max is a number -->
<xsl:variable name="maxIsNumber">
<xsl:call-template name="checkNumber">
<xsl:with-param name="test">
<xsl:value-of select="@max"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:message terminate="no">$maxIsNumber:<xsl:value-of select="$maxIsNumber"/></xsl:message>
<!-- check if min is a number -->
<xsl:variable name="minIsNumber">
<xsl:call-template name="checkNumber">
<xsl:with-param name="test">
<xsl:value-of select="@min"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<!-- check if precision is a number -->
<xsl:variable name="precisionIsNNI">
<xsl:call-template name="checkNonNegInt">
<xsl:with-param name="test">
<xsl:value-of select="@precision"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<!-- check if scale is a number -->
<xsl:variable name="scaleIsNNI">
<xsl:call-template name="checkNonNegInt">
<xsl:with-param name="test">
<xsl:value-of select="@scale"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<!-- write xfm:max restriction -->
<xsl:if test="string-length(@max) > 0 and
not(@max=$maxInfinity) and
$maxIsNumber='false'">
<xsl:attribute name="xfm:maxInclusive">
<xsl:value-of select="@max"/>
</xsl:attribute>
</xsl:if>
<!-- write xfm:min restriction -->
<xsl:if test="string-length(@min) > 0 and
not(@min=$minInfinity) and
$minIsNumber='false'">
<xsl:attribute name="xfm:minInclusive">
<xsl:value-of select="@min"/>
</xsl:attribute>
</xsl:if>
<!-- write xfm:precision restriction -->
<xsl:if test="string-length(@precision) > 0 and
not(@precision=$unlimitedPrecision) and
$precisionIsNNI='false'">
<xsl:attribute name="xfm:precision">
<xsl:value-of select="@precision"/>
</xsl:attribute>
</xsl:if>
<!-- write xfm:scale restriction -->
<xsl:if test="string-length(@scale) > 0 and
not(@scale=$unlimitedScale) and
$scaleIsNNI='false'">
<xsl:attribute name="xfm:scale">
<xsl:value-of select="@scale"/>
</xsl:attribute>
</xsl:if>
<!-- write xsd:max restriction -->
<xsl:choose>
<xsl:when test="$maxIsNumber='true'">
<xsl:element name="xsd:maxInclusive">
<xsl:attribute name="value">
<xsl:value-of select="@max"/>
</xsl:attribute>
</xsl:element>
</xsl:when>
<xsl:when test="count(max) > 0">
<xsl:element name="xsd:maxInclusive">
<xsl:attribute name="value">
<xsl:value-of select="max[1]"/>
</xsl:attribute>
</xsl:element>
</xsl:when>
</xsl:choose>
<!-- write xsd:min restriction -->
<xsl:choose>
<xsl:when test="$minIsNumber='true'">
<xsl:element name="xsd:minInclusive">
<xsl:attribute name="value">
<xsl:value-of select="@min"/>
</xsl:attribute>
</xsl:element>
</xsl:when>
<xsl:when test="count(min) > 0">
<xsl:element name="xsd:minInclusive">
<xsl:attribute name="value">
<xsl:value-of select="min[1]"/>
</xsl:attribute>
</xsl:element>
</xsl:when>
</xsl:choose>
<!-- write xsd:precision restriction -->
<xsl:choose>
<xsl:when test="$precisionIsNNI='true'">
<xsl:element name="xsd:precision">
<xsl:attribute name="value">
<xsl:value-of select="@precision"/>
</xsl:attribute>
</xsl:element>
</xsl:when>
<xsl:when test="count(precision) > 0">
<xsl:element name="xsd:precision">
<xsl:attribute name="value">
<xsl:value-of select="precision[1]"/>
</xsl:attribute>
</xsl:element>
</xsl:when>
</xsl:choose>
<!-- write xsd:scale restriction -->
<xsl:choose>
<xsl:when test="$scaleIsNNI='true'">
<xsl:element name="xsd:scale">
<xsl:attribute name="value">
<xsl:value-of select="@scale"/>
</xsl:attribute>
</xsl:element>
</xsl:when>
<xsl:when test="count(scale) > 0">
<xsl:element name="xsd:scale">
<xsl:attribute name="value">
<xsl:value-of select="scale[1]"/>
</xsl:attribute>
</xsl:element>
</xsl:when>
</xsl:choose>
</xsl:template>
<!--
currency element
-->
<!-- template: matches="currency"
function: converts a currency into a currency.
parameters: none
output: partially converted definition
-->
<xsl:template match="money">
<!-- create definition -->
<xsl:variable name="definition">
<xsl:element name="xsd:simpleType">
<xsl:choose>
<!-- if we have closed range, or no enumeration value, we can
create simple type -->
<xsl:when test="@enum='closed' or
count(value)=0">
<xsl:element name="xsd:restriction">
<xsl:attribute name="base">xfm:currency</xsl:attribute>
<xsl:call-template name="restrictCurrency"/>
<xsl:apply-templates select="value"/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:element name="xsd:union">
<xsl:element name="xsd:simpleType">
<xsl:element name="xsd:restriction">
<xsl:attribute name="base">xfm:currency</xsl:attribute>
<xsl:call-template name="restrictCurrency"/>
<xsl:apply-templates select="value"/>
</xsl:element>
</xsl:element>
<xsl:element name="xsd:simpleType">
<xsl:element name="xsd:restriction">
<xsl:attribute name="base">xfm:currency</xsl:attribute>
<xsl:call-template name="restrictCurrency"/>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:variable>
<!-- if we have a name, we can create an element or attribute,
otherwise we're part of a union -->
<xsl:choose>
<xsl:when test="string-length(@name) > 0">
<!-- create element or attribute -->
<xsl:element name="xsd:element">
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<!-- check common attributes -->
<xsl:call-template name="checkAttributes"/>
<xsl:choose>
<!-- if we have no children, and no other restrictions,
we can make a short definition -->
<xsl:when test='count(child::node())=0 and
(string-length(@min)=0 or @min=0) and
(string-length(@max)=0 or @max=$maxLengthSpecial)'>
<xsl:attribute name="type">xfm:currency</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<!-- dump full definition -->
<xsl:copy-of select="$definition"/>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<!-- just dumpe definition -->
<xsl:copy-of select="$definition"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- template: name="restrictCurrency"
function: add erstrictions to a currency
parameters: a currency context node with the following attributes
@max
@min
@mask
and the following child elements
<min>
<max>
<mask>
output: elements to represent the restrictions
-->
<xsl:template name="restrictCurrency">
<!-- this is currently not implemented, because it is unclear what min, max
or mask are supposed to mean -->
</xsl:template>
<!--
money element
-->
<!-- template: matches="money"
function: converts a money into a money.
parameters: none
output: partially converted definition
-->
<xsl:template match="money">
<!-- only elements of type money can be converted into Schemas -->
<xsl:choose>
<xsl:when test="string-length(@name) = 0">
<xsl:message terminate="no">
An anonymous money definition is not supported.
</xsl:message>
<xsl:comment> Anonymous money definition dropped </xsl:comment>
</xsl:when>
<xsl:otherwise>
<xsl:element name="xsd:element">
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<!-- check common attributes -->
<xsl:call-template name="checkAttributes"/>
<xsl:attribute name="type">xfm:money</xsl:attribute>
<!-- add allowCurrency -->
<xsl:if test="string-length(@allowCurrency) > 0">
<xsl:attribute name="xfm:allowCurrency">
<xsl:value-of select="@allowCurrency"/>
</xsl:attribute>
</xsl:if>
<!-- add min value -->
<xsl:if test="string-length(@min) > 0 and
not(@min=$minInfinity)">
<xsl:attribute name="xfm:minInclusive">
<xsl:value-of select="@min"/>
</xsl:attribute>
</xsl:if>
<!-- add max value -->
<xsl:if test="string-length(@max) > 0 and
not(@max=$maxInfinity)">
<xsl:attribute name="xfm:maxInclusive">
<xsl:value-of select="@max"/>
</xsl:attribute>
</xsl:if>
<!-- add precision value -->
<xsl:if test="string-length(@precision) > 0 and
not(@precision=$unlimitedPrecision)">
<xsl:attribute name="xfm:precision">
<xsl:value-of select="@precision"/>
</xsl:attribute>
</xsl:if>
<!-- add scale value -->
<xsl:if test="string-length(@scale) > 0 and
not(@scale=$unlimitedScale)">
<xsl:attribute name="xfm:scale">
<xsl:value-of select="@scale"/>
</xsl:attribute>
</xsl:if>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!--
date element
-->
<!-- template: matches="date"
function: converts a date into an xsd:date.
parameters: none
output: converted definition
-->
<xsl:template match="date">
<!-- create definition -->
<xsl:variable name="definition">
<xsl:element name="xsd:simpleType">
<xsl:choose>
<!-- if we have closed range, or no enumeration value, we can
create simple type -->
<xsl:when test="@range='closed' or
count(value)=0">
<xsl:element name="xsd:restriction">
<xsl:attribute name="base">xsd:date</xsl:attribute>
<xsl:call-template name="restrictDate"/>
<xsl:apply-templates select="value"/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:element name="xsd:union">
<xsl:element name="xsd:simpleType">
<xsl:element name="xsd:restriction">
<xsl:attribute name="base">xsd:date</xsl:attribute>
<xsl:call-template name="restrictDate"/>
<xsl:apply-templates select="value"/>
</xsl:element>
</xsl:element>
<xsl:element name="xsd:simpleType">
<xsl:element name="xsd:restriction">
<xsl:attribute name="base">xsd:date</xsl:attribute>
<xsl:call-template name="restrictDate"/>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:variable>
<!-- if we have a name, we can create an element or attribute,
otherwise we're part of a union -->
<xsl:choose>
<xsl:when test="string-length(@name) > 0">
<!-- create element -->
<xsl:element name="xsd:element">
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<!-- check common attributes -->
<xsl:call-template name="checkAttributes"/>
<xsl:choose>
<!-- if we have no children, and no other restrictions,
we can make a short definition -->
<xsl:when test='count(child::node())=0 and
string-length(@min)=0 and
string-length(@max)=0 and
(string-length(@precision)=0 or
@precision="days")'>
<xsl:attribute name="type">xsd:date</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<!-- dump full definition -->
<xsl:copy-of select="$definition"/>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<!-- just dumpe definition -->
<xsl:copy-of select="$definition"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- template: name="restrictDate"
function: add erstrictions to a date
parameters: a date context node with the following attributes
@max
@min
@precision
and the following child elements
<min>
<max>
<precision>
output: elements to represent the restrictions
-->
<xsl:template name="restrictDate">
<!-- check if @max is a date -->
<xsl:variable name="maxIsDate">
<xsl:call-template name="checkDate">
<xsl:with-param name="test">
<xsl:value-of select="@max"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<!-- check if @min is a date -->
<xsl:variable name="minIsDate">
<xsl:call-template name="checkDate">
<xsl:with-param name="test">
<xsl:value-of select="@min"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<!-- check if precision is valid -->
<xsl:variable name="precisionIsValid">
<xsl:call-template name="checkDatePrecision">
<xsl:with-param name="test">
<xsl:value-of select="@precision"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<!-- write xfm:max restriction -->
<xsl:if test="string-length(@max) > 0 and
$maxIsDate='false'">
<xsl:attribute name="xfm:max">
<xsl:value-of select="@max"/>
</xsl:attribute>
</xsl:if>
<!-- write xfm:min restriction -->
<xsl:if test="string-length(@min) > 0 and
$minIsDate='false'">
<xsl:attribute name="xfm:min">
<xsl:value-of select="@min"/>
</xsl:attribute>
</xsl:if>
<!-- write xfm:precision restriction -->
<xsl:if test="string-length(@precision) > 0 and
$precisionIsValid='false'">
<xsl:attribute name="xfm:precision">
<xsl:value-of select="@precision"/>
</xsl:attribute>
</xsl:if>
<!-- write xsd:max restriction -->
<xsl:choose>
<xsl:when test="$maxIsDate='true'">
<xsl:element name="xsd:max">
<xsl:attribute name="value">
<xsl:value-of select="@max"/>
</xsl:attribute>
</xsl:element>
</xsl:when>
<xsl:when test="count(max) > 0">
<xsl:element name="xsd:max">
<xsl:attribute name="value">
<xsl:value-of select="max[1]"/>
</xsl:attribute>
</xsl:element>
</xsl:when>
</xsl:choose>
<!-- write xsd:min restriction -->
<xsl:choose>
<xsl:when test="$minIsDate='true'">
<xsl:element name="xsd:min">
<xsl:attribute name="value">
<xsl:value-of select="@min"/>
</xsl:attribute>
</xsl:element>
</xsl:when>
<xsl:when test="count(min) > 0">
<xsl:element name="xsd:min">
<xsl:attribute name="value">
<xsl:value-of select="min[1]"/>
</xsl:attribute>
</xsl:element>
</xsl:when>
</xsl:choose>
<!-- write xsd:duration restriction -->
<xsl:choose>
<xsl:when test="$precisionIsValid='true'">
<xsl:call-template name="writeDatePrecision">
<xsl:with-param name="precision">
<xsl:value-of select="@precision"/>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:when test="count(precision) > 0">
<xsl:call-template name="writeDatePrecision">
<xsl:with-param name="precision">
<xsl:value-of select="precision[1]"/>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
</xsl:choose>
</xsl:template>
<!-- template: name="writeDatePrecision"
function: writes the definitions to matche the precision
attribute
parameters: $precision: one of years, months, days
output: proper definition to allow only the requested
precision
-->
<xsl:template name="writeDatePrecision">
<xsl:param name="precision"/>
<xsl:choose>
<xsl:when test="$precision='years'">
<xsl:element name="xsd:duration">
<xsl:attribute name="value">P1Y</xsl:attribute>
</xsl:element>
<xsl:element name="xsd:pattern">
<xsl:attribute name="value">\d*\d{4}</xsl:attribute>
</xsl:element>
</xsl:when>
<xsl:when test="$precision='months'">
<xsl:element name="xsd:duration">
<xsl:attribute name="value">P1M</xsl:attribute>
</xsl:element>
<xsl:element name="xsd:pattern">
<xsl:attribute name="value">\d*\d{4}-\d{2}</xsl:attribute>
</xsl:element>
</xsl:when>
</xsl:choose>
</xsl:template>
<!--
time element
-->
<!-- template: matches="time"
function: converts a time into an xsd:time.
parameters: none
output: converted definition
-->
<xsl:template match="time">
<!-- create definition -->
<xsl:variable name="definition">
<xsl:element name="xsd:simpleType">
<xsl:choose>
<!-- if we have closed range, or no enumeration value, we can
create simple type -->
<xsl:when test="@range='closed' or
count(value)=0">
<xsl:element name="xsd:restriction">
<xsl:attribute name="base">xsd:time</xsl:attribute>
<xsl:call-template name="restrictTime"/>
<xsl:apply-templates select="value"/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:element name="xsd:union">
<xsl:element name="xsd:simpleType">
<xsl:element name="xsd:restriction">
<xsl:attribute name="base">xsd:time</xsl:attribute>
<xsl:call-template name="restrictTime"/>
<xsl:apply-templates select="value"/>
</xsl:element>
</xsl:element>
<xsl:element name="xsd:simpleType">
<xsl:element name="xsd:restriction">
<xsl:attribute name="base">xsd:time</xsl:attribute>
<xsl:call-template name="restrictTime"/>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:variable>
<!-- if we have a name, we can create an element or attribute,
otherwise we're part of a union -->
<xsl:choose>
<xsl:when test="string-length(@name) > 0">
<!-- create element -->
<xsl:element name="xsd:element">
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<!-- check common attributes -->
<xsl:call-template name="checkAttributes"/>
<xsl:choose>
<!-- if we have no children, and no other restrictions,
we can make a short definition -->
<xsl:when test='count(child::node())=0 and
string-length(@min)=0 and
string-length(@max)=0 and
(string-length(@precision)=0 or
@precision="seconds")'>
<xsl:attribute name="type">xsd:time</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<!-- dump full definition -->
<xsl:copy-of select="$definition"/>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<!-- just dumpe definition -->
<xsl:copy-of select="$definition"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- template: name="restrictTime"
function: add erstrictions to a time
parameters: a time context node with the following attributes
@max
@min
@precision
and the following child elements
<min>
<max>
<precision>
output: elements to represent the restrictions
-->
<xsl:template name="restrictTime">
<!-- check if max is a time -->
<xsl:variable name="maxIsTime">
<xsl:call-template name="checkTime">
<xsl:with-param name="test">
<xsl:value-of select="@max"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<!-- check if min is a time -->
<xsl:variable name="minIsTime">
<xsl:call-template name="checkTime">
<xsl:with-param name="test">
<xsl:value-of select="@min"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<!-- check if precision is valid -->
<xsl:variable name="precisionIsValid">
<xsl:call-template name="checkTimePrecision">
<xsl:with-param name="test">
<xsl:value-of select="@precision"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<!-- write xfm:max restriction -->
<xsl:if test="string-length(@max) > 0 and
$maxIsTime='false'">
<xsl:attribute name="xfm:max">
<xsl:value-of select="@max"/>
</xsl:attribute>
</xsl:if>
<!-- write xfm:min restriction -->
<xsl:if test="string-length(@min) > 0 and
$minIsTime='false'">
<xsl:attribute name="xfm:min">
<xsl:value-of select="@min"/>
</xsl:attribute>
</xsl:if>
<!-- write xfm:precision restriction -->
<xsl:if test="string-length(@precision) > 0 and
$precisionIsValid='false'">
<xsl:attribute name="xfm:precision">
<xsl:value-of select="@precision"/>
</xsl:attribute>
</xsl:if>
<!-- write xsd:max restriction -->
<xsl:choose>
<xsl:when test="$maxIsTime='true'">
<xsl:element name="xsd:max">
<xsl:attribute name="value">
<xsl:value-of select="@max"/>
</xsl:attribute>
</xsl:element>
</xsl:when>
<xsl:when test="count(max) > 0">
<xsl:element name="xsd:max">
<xsl:attribute name="value">
<xsl:value-of select="max[1]"/>
</xsl:attribute>
</xsl:element>
</xsl:when>
</xsl:choose>
<!-- write xsd:min restriction -->
<xsl:choose>
<xsl:when test="$minIsTime='true'">
<xsl:element name="xsd:min">
<xsl:attribute name="value">
<xsl:value-of select="@min"/>
</xsl:attribute>
</xsl:element>
</xsl:when>
<xsl:when test="count(min) > 0">
<xsl:element name="xsd:min">
<xsl:attribute name="value">
<xsl:value-of select="min[1]"/>
</xsl:attribute>
</xsl:element>
</xsl:when>
</xsl:choose>
<!-- write xsd:duration restriction -->
<xsl:choose>
<xsl:when test="$precisionIsValid='true'">
<xsl:call-template name="writeTimePrecision">
<xsl:with-param name="precision">
<xsl:value-of select="@precision"/>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:when test="count(precision) > 0">
<xsl:call-template name="writeTimePrecision">
<xsl:with-param name="precision">
<xsl:value-of select="precision[1]"/>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
</xsl:choose>
</xsl:template>
<!-- template: name="writeTimePrecision"
function: writes the definitions to matche the precision
attribute
parameters: $precision: one of hours, minutes, seconds
output: proper definition to allow only the requested
precision
-->
<xsl:template name="writeTimePrecision">
<xsl:param name="precision"/>
<xsl:choose>
<xsl:when test="$precision='hours'">
<xsl:element name="xsd:duration">
<xsl:attribute name="value">PT60M</xsl:attribute>
</xsl:element>
<xsl:element name="xsd:pattern">
<xsl:attribute name="value">
<xsl:text>([01][0-9]|2[0-3])(:00(:00(.000)?)?)?</xsl:text>
</xsl:attribute>
</xsl:element>
</xsl:when>
<xsl:when test="$precision='minutes'">
<xsl:element name="xsd:duration">
<xsl:attribute name="value">PT60S</xsl:attribute>
</xsl:element>
<xsl:element name="xsd:pattern">
<xsl:attribute name="value">
<xsl:text>([01][0-9]|2[0-3])</xsl:text>
<xsl:text>(:[0-5][0-9](:00(.000)?)?)?</xsl:text>
</xsl:attribute>
</xsl:element>
</xsl:when>
</xsl:choose>
</xsl:template>
<!--
duration element
-->
<!-- template: matches="duration"
function: converts a duration into an xsd:timeDuration.
parameters: none
output: converted definition
-->
<xsl:template match="duration">
<!-- create definition -->
<xsl:variable name="definition">
<xsl:element name="xsd:simpleType">
<xsl:choose>
<!-- if we have closed range, or no enumeration value, we can
create simple type -->
<xsl:when test="@range='closed' or
count(value)=0">
<xsl:element name="xsd:restriction">
<xsl:attribute name="base">xsd:timeDuration</xsl:attribute>
<xsl:call-template name="restrictDuration"/>
<xsl:apply-templates select="value"/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:element name="xsd:union">
<xsl:element name="xsd:simpleType">
<xsl:element name="xsd:restriction">
<xsl:attribute name="base">
<xsl:text>xsd:timeDuration</xsl:text>
</xsl:attribute>
<xsl:call-template name="restrictDuration"/>
<xsl:apply-templates select="value"/>
</xsl:element>
</xsl:element>
<xsl:element name="xsd:simpleType">
<xsl:element name="xsd:restriction">
<xsl:attribute name="base">
<xsl:text>xsd:timeDuration</xsl:text>
</xsl:attribute>
<xsl:call-template name="restrictDuration"/>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:variable>
<!-- if we have a name, we can create an element or attribute,
otherwise we're part of a union -->
<xsl:choose>
<xsl:when test="string-length(@name) > 0">
<!-- create element or attribute -->
<xsl:element name="xsd:{@as}">
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<!-- check common attributes -->
<xsl:call-template name="checkAttributes"/>
<xsl:choose>
<!-- if we have no children, and no other restrictions,
we can make a short definition -->
<xsl:when test='count(child::node())=0 and
string-length(@min)=0 and
string-length(@max)=0 and
(string-length(@precision)=0 or
@precision="seconds")'>
<xsl:attribute name="type">xsd:timeDuration</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<!-- dump full definition -->
<xsl:copy-of select="$definition"/>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<!-- just dumpe definition -->
<xsl:copy-of select="$definition"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- template: name="restrictDuration"
function: add erstrictions to a duration
parameters: a duration context node with the following attributes
@max
@min
@precision
and the following child elements
<min>
<max>
<precision>
output: elements to represent the restrictions
-->
<xsl:template name="restrictDuration">
<!-- check if max is a duration -->
<xsl:variable name="maxIsDuration">
<xsl:call-template name="checkDuration">
<xsl:with-param name="test">
<xsl:value-of select="@max"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<!-- check if min is a duration -->
<xsl:variable name="minIsDuration">
<xsl:call-template name="checkDuration">
<xsl:with-param name="test">
<xsl:value-of select="@min"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<!-- check if precision is valid -->
<xsl:variable name="precisionIsValid">
<xsl:variable name="test">
<xsl:call-template name="checkDatePrecision">
<xsl:with-param name="test">
<xsl:value-of select="@precision"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$test='false'">
<xsl:call-template name="checkTimePrecision">
<xsl:with-param name="test">
<xsl:value-of select="@precision"/>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$test"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- write xfm:max restriction -->
<xsl:if test="string-length(@max) > 0 and
$maxIsDuration='false'">
<xsl:attribute name="xfm:max">
<xsl:value-of select="@max"/>
</xsl:attribute>
</xsl:if>
<!-- write xfm:min restriction -->
<xsl:if test="string-length(@min) > 0 and
$minIsDuration='false'">
<xsl:attribute name="xfm:min">
<xsl:value-of select="@min"/>
</xsl:attribute>
</xsl:if>
<!-- write xfm:precision restriction -->
<xsl:if test="string-length(@precision) > 0 and
$precisionIsValid='false'">
<xsl:attribute name="xfm:precision">
<xsl:value-of select="@precision"/>
</xsl:attribute>
</xsl:if>
<!-- write xsd:max restriction -->
<xsl:choose>
<xsl:when test="$maxIsDuration='true'">
<xsl:element name="xsd:max">
<xsl:attribute name="value">
<xsl:value-of select="@max"/>
</xsl:attribute>
</xsl:element>
</xsl:when>
<xsl:when test="count(max) > 0">
<xsl:element name="xsd:max">
<xsl:attribute name="value">
<xsl:value-of select="max[1]"/>
</xsl:attribute>
</xsl:element>
</xsl:when>
</xsl:choose>
<!-- write xsd:min restriction -->
<xsl:choose>
<xsl:when test="$minIsDuration='true'">
<xsl:element name="xsd:min">
<xsl:attribute name="value">
<xsl:value-of select="@min"/>
</xsl:attribute>
</xsl:element>
</xsl:when>
<xsl:when test="count(min) > 0">
<xsl:element name="xsd:min">
<xsl:attribute name="value">
<xsl:value-of select="min[1]"/>
</xsl:attribute>
</xsl:element>
</xsl:when>
</xsl:choose>
<!-- write xsd:duration restriction -->
<xsl:choose>
<xsl:when test="$precisionIsValid='true'">
<xsl:call-template name="writeDurationPrecision">
<xsl:with-param name="precision">
<xsl:value-of select="@precision"/>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:when test="count(precision) > 0">
<xsl:call-template name="writeDurationPrecision">
<xsl:with-param name="precision">
<xsl:value-of select="precision[1]"/>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
</xsl:choose>
</xsl:template>
<!-- template: name="writeDurationPrecision"
function: writes the definitions to matche the precision
attribute
parameters: $precision: one of hours, minutes, seconds
output: proper definition to allow only the requested
precision
-->
<xsl:template name="writeDurationPrecision">
<xsl:param name="precision"/>
<xsl:choose>
<xsl:when test="$precision='years'">
<xsl:element name="xsd:pattern">
<xsl:attribute name="value">
<xsl:text>P(\d+(\.\d+)?|\.\d+)Y</xsl:text>
</xsl:attribute>
</xsl:element>
</xsl:when>
<xsl:when test="$precision='months'">
<xsl:element name="xsd:pattern">
<xsl:attribute name="value">
<xsl:text>P(\d+(\.\d+)?|\.\d+)Y|</xsl:text>
<xsl:text>P(\d+Y)?(\d+(\.\d+)?|\.\d+)M</xsl:text>
</xsl:attribute>
</xsl:element>
</xsl:when>
<xsl:when test="$precision='days'">
<xsl:element name="xsd:pattern">
<xsl:attribute name="value">
<xsl:text>P(\d+(\.\d+)?|\.\d+)Y|</xsl:text>
<xsl:text>P(\d+Y)?(\d+(\.\d+)?|\.\d+)M|</xsl:text>
<xsl:text>P(\d+Y)?(\d+M)?(\d+(\.\d+)?|\.\d+)D</xsl:text>
</xsl:attribute>
</xsl:element>
</xsl:when>
<xsl:when test="$precision='hours'">
<xsl:element name="xsd:pattern">
<xsl:attribute name="value">
<xsl:text>P(\d+(\.\d+)?|\.\d+)Y|</xsl:text>
<xsl:text>P(\d+Y)?(\d+(\.\d+)?|\.\d+)M|</xsl:text>
<xsl:text>P(\d+Y)?(\d+M)?(\d+(\.\d+)?|\.\d+)D|</xsl:text>
<xsl:text>P(\d+Y)?(\d+M)?(\d+D)?T(\d+(\.\d+)?|</xsl:text>
<xsl:text>\.\d+)H</xsl:text>
</xsl:attribute>
</xsl:element>
</xsl:when>
<xsl:when test="$precision='minutes'">
<xsl:element name="xsd:pattern">
<xsl:attribute name="value">
<xsl:text>P(\d+(\.\d+)?|\.\d+)Y|</xsl:text>
<xsl:text>P(\d+Y)?(\d+(\.\d+)?|\.\d+)M|</xsl:text>
<xsl:text>P(\d+Y)?(\d+M)?(\d+(\.\d+)?|\.\d+)D|</xsl:text>
<xsl:text>P(\d+Y)?(\d+M)?(\d+D)?T(\d+(\.\d+)?|</xsl:text>
<xsl:text>\.\d+)H|</xsl:text>
<xsl:text>P(\d+Y)?(\d+M)?(\d+D)?T(\d+H)?</xsl:text>
<xsl:text>(\d(\.\d+)?|\.\d+)M</xsl:text>
</xsl:attribute>
</xsl:element>
</xsl:when>
</xsl:choose>
</xsl:template>
<!--
uri element
-->
<!-- template: matches="uri"
function: converts a uri into an xsd:uriReference.
parameters: none
output: converted definition
-->
<xsl:template match="uri">
<!-- create definition -->
<xsl:variable name="definition">
<xsl:element name="xsd:simpleType">
<xsl:choose>
<!-- if we have closed range, or no enumeration value, we can
create simple type -->
<xsl:when test="@range='closed' or
count(value)=0">
<xsl:element name="xsd:restriction">
<xsl:attribute name="base">xsd:uriReference</xsl:attribute>
<xsl:call-template name="restrictUri"/>
<xsl:apply-templates select="value"/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:element name="xsd:union">
<xsl:element name="xsd:simpleType">
<xsl:element name="xsd:restriction">
<xsl:attribute name="base">
<xsl:text>xsd:uriReference</xsl:text>
</xsl:attribute>
<xsl:call-template name="restrictUri"/>
<xsl:apply-templates select="value"/>
</xsl:element>
</xsl:element>
<xsl:element name="xsd:simpleType">
<xsl:element name="xsd:restriction">
<xsl:attribute name="base">
<xsl:text>xsd:uriReference</xsl:text>
</xsl:attribute>
<xsl:call-template name="restrictUri"/>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:variable>
<!-- if we have a name, we can create an element or attribute,
otherwise we're part of a union -->
<xsl:choose>
<xsl:when test="string-length(@name) > 0">
<!-- create element -->
<xsl:element name="xsd:element">
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<!-- check common attributes -->
<xsl:call-template name="checkAttributes"/>
<xsl:choose>
<!-- if we have no children, and no other restrictions,
we can make a short definition -->
<xsl:when test='count(child::node())=0 and
string-length(@scheme)=0'>
<xsl:attribute name="type">xsd:uriReference</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<!-- dump full definition -->
<xsl:copy-of select="$definition"/>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<!-- just dumpe definition -->
<xsl:copy-of select="$definition"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- template: name="restrictUri"
function: add restrictions to a uri
parameters: a duration context node with the following attributes
@scheme
and the following child elements
<scheme>
output: elements to represent the restrictions
-->
<xsl:template name="restrictUri">
<!-- make pattern from scheme -->
<xsl:variable name="pattern">
<xsl:for-each select="scheme">
<xsl:call-template name="convertScheme">
<xsl:with-param name="scheme">
<xsl:value-of select="."/>
</xsl:with-param>
</xsl:call-template>
<xsl:if test="not(position()=last())">
<xsl:text>|</xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:if test="@scheme">
<xsl:if test="count(scheme) > 0">
<xsl:text>|</xsl:text>
</xsl:if>
<xsl:call-template name="convertScheme">
<xsl:with-param name="scheme">
<xsl:value-of select="@scheme"/>
</xsl:with-param>
</xsl:call-template>
</xsl:if>
</xsl:variable>
<xsl:if test="string-length($pattern) > 0">
<xsl:element name="xsd:pattern">
<xsl:attribute name="value">
<xsl:value-of select="$pattern"/>
</xsl:attribute>
</xsl:element>
</xsl:if>
</xsl:template>
<!-- template: name="convertScheme"
function: converts a scheme to a pattern
parameters: scheme : the scheme to transform
output: a pattern with the same meaning
-->
<xsl:template name="convertScheme">
<xsl:param name="scheme"/>
<xsl:choose>
<xsl:when test="contains($scheme, ' ')">
<!-- splitt scheme -->
<xsl:call-template name="convertScheme">
<xsl:with-param name="scheme">
<xsl:value-of select="substring-before($scheme, ' ')"/>
</xsl:with-param>
</xsl:call-template>
<xsl:text>|</xsl:text>
<xsl:call-template name="convertScheme">
<xsl:with-param name="scheme">
<xsl:value-of select="substring-after($scheme, ' ')"/>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:text>(</xsl:text>
<xsl:choose>
<xsl:when test="$scheme='mailto'">
<xsl:value-of select="$scheme"/>
<xsl:text>:.*</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$scheme"/>
<xsl:text>://.*</xsl:text>
</xsl:otherwise>
</xsl:choose>
<xsl:text>)</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!--
binary element
-->
<!-- template: matches="binary"
function: converts a binary into an xsd:binary.
parameters: none
output: converted definition
-->
<xsl:template match="binary">
<!-- create definition -->
<xsl:variable name="definition">
<xsl:element name="xsd:simpleType">
<xsl:element name="xsd:restriction">
<xsl:attribute name="base">xsd:binary</xsl:attribute>
<xsl:call-template name="restrictBinary"/>
</xsl:element>
</xsl:element>
</xsl:variable>
<!-- if we have a name, we can create an element or attribute,
otherwise we're part of a union -->
<xsl:choose>
<xsl:when test="string-length(@name) > 0">
<!-- create element -->
<xsl:element name="xsd:element">
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<!-- check common attributes -->
<xsl:call-template name="checkAttributes"/>
<xsl:choose>
<!-- if we have no children, and no other restrictions,
we can make a short definition -->
<xsl:when test='count(child::node())=0 and
string-length(@type)=0'>
<xsl:attribute name="type">xsd:binary</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<!-- dump full definition -->
<xsl:copy-of select="$definition"/>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<!-- just dumpe definition -->
<xsl:copy-of select="$definition"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- template: name="restrictBinary"
function: add erstrictions to a binary
parameters: a duration context node with the following attributes
@length
@max
@min
@mediaType
and the following child elements
<length>
<min>
<max>
<mediaType>
output: elements to represent the restrictions
-->
<xsl:template name="restrictBinary">
<!-- converte list of types into media attribute -->
<xsl:attribute name="xfm:mediaType">
<xsl:for-each select="mediaType">
<xsl:variable name="isMedia">
<xsl:call-template name="checkMedia">
<xsl:with-param name="test">
<xsl:value-of select="."/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:if test="$isMedia='true'">
<xsl:value-of select="."/>
<xsl:if test="not(position()=last())">
<xsl:text> </xsl:text>
</xsl:if>
</xsl:if>
</xsl:for-each>
<xsl:if test="not(string-length(@mediaType)=0)">
<xsl:text> </xsl:text>
<xsl:variable name="isMedia">
<xsl:call-template name="checkMedia">
<xsl:with-param name="test">
<xsl:value-of select="@mediaType"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:if test="isMedia='true'">
<xsl:value-of select="@mediaType"/>
</xsl:if>
</xsl:if>
</xsl:attribute>
<!-- check if @length is an non negative integer -->
<xsl:variable name="lengthIsNNI">
<xsl:call-template name="checkNonNegInt">
<xsl:with-param name="test">
<xsl:value-of select="@length"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<!-- check if @max is an non negative integer -->
<xsl:variable name="maxIsNNI">
<xsl:call-template name="checkNonNegInt">
<xsl:with-param name="test">
<xsl:value-of select="@max"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<!-- check if @min as an non negative integer -->
<xsl:variable name="minIsNNI">
<xsl:call-template name="checkNonNegInt">
<xsl:with-param name="test">
<xsl:value-of select="@min"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<!-- write xfm:length restriction -->
<xsl:if test="string-length(@length) > 0 and
not(@length=$maxLengthSpecial) and
$lengthIsNNI='false'">
<xsl:attribute name="xfm:length">
<xsl:value-of select="@length"/>
</xsl:attribute>
</xsl:if>
<!-- write xfm:maxLength restriction -->
<xsl:if test="string-length(@max) > 0 and
not(@max=$maxLengthSpecial) and
$maxIsNNI='false'">
<xsl:attribute name="xfm:maxLength">
<xsl:value-of select="@max"/>
</xsl:attribute>
</xsl:if>
<!-- write xfm:minLength restriction -->
<xsl:if test="string-length(@min) > 0 and
not(@min='0') and
$minIsNNI='false'">
<xsl:attribute name="xfm:minLength">
<xsl:value-of select="@min"/>
</xsl:attribute>
</xsl:if>
<!-- write xsd:length restriction -->
<xsl:choose>
<xsl:when test="$lengthIsNNI='true'">
<xsl:if test="not(@length=$maxLengthSpecial)">
<xsl:element name="xsd:length">
<xsl:attribute name="value">
<xsl:value-of select="@length"/>
</xsl:attribute>
</xsl:element>
</xsl:if>
</xsl:when>
<xsl:when test="count(length) > 0">
<xsl:element name="xsd:length">
<xsl:attribute name="value">
<xsl:value-of select="length[1]"/>
</xsl:attribute>
</xsl:element>
</xsl:when>
</xsl:choose>
<!-- write xsd:maxLength restriction -->
<xsl:choose>
<xsl:when test="$maxIsNNI='true'">
<xsl:if test="not(@max=$maxLengthSpecial)">
<xsl:element name="xsd:maxLength">
<xsl:attribute name="value">
<xsl:value-of select="@max"/>
</xsl:attribute>
</xsl:element>
</xsl:if>
</xsl:when>
<xsl:when test="count(max) > 0">
<xsl:element name="xsd:maxLength">
<xsl:attribute name="value">
<xsl:value-of select="max[1]"/>
</xsl:attribute>
</xsl:element>
</xsl:when>
</xsl:choose>
<!-- write xsd:minLength restriction -->
<xsl:choose>
<xsl:when test="$minIsNNI='true'">
<xsl:if test="not(@min='0')">
<xsl:element name="xsd:minLength">
<xsl:attribute name="value">
<xsl:value-of select="@min"/>
</xsl:attribute>
</xsl:element>
</xsl:if>
</xsl:when>
<xsl:when test="count(min) > 0">
<xsl:element name="xsd:min">
<xsl:attribute name="value">
<xsl:value-of select="min[1]"/>
</xsl:attribute>
</xsl:element>
</xsl:when>
</xsl:choose>
</xsl:template>
<!--
element element
-->
<!-- template: matches="element"
function: converts a element into an xsd:element.
parameters: none
output: converted definition
-->
<xsl:template match="element">
<xsl:choose>
<xsl:when test="string-length(@name)=0">
<xsl:message terminate="no">
An anonymous element definition is not supported.
</xsl:message>
<xsl:comment> Anonymous element definition dropped </xsl:comment>
</xsl:when>
<xsl:otherwise>
<xsl:element name="xsd:element">
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<!-- check common attributes -->
<xsl:call-template name="checkAttributes"/>
<xsl:attribute name="type">
<xsl:value-of select="@type"/>
</xsl:attribute>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!--
value element
-->
<!-- template: matches="value"
function: converte value into an enumeration.
parameters: none
output: <enumeration> that represents the value
-->
<xsl:template match="value">
<xsl:element name="xsd:enumeration">
<xsl:attribute name="value">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:element>
</xsl:template>
<!--
Named templates
-->
<!--
Datatype checks
-->
<!-- template: name="checkXpression"
function: checks if a given string is an Xpression or not
parameter: test
output: true if it's an Xpression
false otherwise
note: this can not work, it must always return true.
But perhapes it can be made to work later
-->
<xsl:template name="checkXpression">
<xsl:param name="test"/>
<!-- we can not test this, so we must return true -->
<xsl:text>true</xsl:text>
</xsl:template>
<!-- template: name="checkBoolean"
function: check if $test is a boolean
parameters: test
output: true if it's a boolean
false otherwise
-->
<xsl:template name="checkBoolean">
<xsl:param name="test"/>
<xsl:choose>
<xsl:when test="true">
<xsl:text>true</xsl:text>
</xsl:when>
<xsl:when test="false">
<xsl:text>true</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>false</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- template: name="checkNumber"
function: check if $test is a number
parameters: test
output: true if it's a number
false otherwise
-->
<xsl:template name="checkNumber">
<xsl:param name="test"/>
<xsl:variable name="number">
<xsl:value-of select="number($test)"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="$number='NaN'">
<xsl:text>false</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>true</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- template: name="checkNonNegInt"
function: check if $test is a non negativ integer
parameters: test
output: true if it's a non negativ integer
false otherwise
-->
<xsl:template name="checkNonNegInt">
<xsl:param name="test"/>
<xsl:variable name="number">
<xsl:value-of select="number($test)"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="$number='NaN'">
<xsl:text>false</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="integer">
<xsl:value-of select="round($number)"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="not($integer=$number)">
<xsl:text>false</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="$integer < 0">
<xsl:text>false</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>true</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- template: name="checkDate"
function: checks if a given string is a date or not
parameter: test :the string to test
output: true if it's a date
false otherwise
note: this does not work, it always returns false
-->
<xsl:template name="checkDate">
<xsl:param name="test"/>
<xsl:text>false</xsl:text>
</xsl:template>
<!-- template: name="checkTime"
function: checks if a given string is a time or not
parameter: test :the string to test
output: true if it's a time
false otherwise
note: this does not work, it always returns false
-->
<xsl:template name="checkTime">
<xsl:param name="test"/>
<xsl:text>false</xsl:text>
</xsl:template>
<!-- template: name="checkDuration"
function: checks if a given string is a duration or not
parameter: test :the string to test
output: true if it's a duration
false otherwise
note: this does not work, it always returns false
-->
<xsl:template name="checkDuration">
<xsl:param name="test"/>
<xsl:text>false</xsl:text>
</xsl:template>
<!-- template: name="checkDatePrecision"
function: checks if a given string is a valid precision for a
date
parameter: test
output: true if it is
false otherwise
-->
<xsl:template name="checkDatePrecision">
<xsl:param name="test"/>
<xsl:choose>
<xsl:when test="$test='years'">
<xsl:text>true</xsl:text>
</xsl:when>
<xsl:when test="$test='months'">
<xsl:text>true</xsl:text>
</xsl:when>
<xsl:when test="$test='dayss'">
<xsl:text>true</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>false</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- template: name="checkTimePrecision"
function: checks if a given string is a valid precision for a
time
parameter: test
output: true if it is
false otherwise
-->
<xsl:template name="checkTimePrecision">
<xsl:param name="test"/>
<xsl:choose>
<xsl:when test="$test='hours'">
<xsl:text>true</xsl:text>
</xsl:when>
<xsl:when test="$test='minutes'">
<xsl:text>true</xsl:text>
</xsl:when>
<xsl:when test="$test='seconds'">
<xsl:text>true</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>false</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- template: name="checkMedia"
function: checks is a string is a valid mimetype
parameters: test : the string to test
output: true : is it's a valid mimetype
false : otherwise
note: does not work, always returns false
-->
<xsl:template name="checkMedia">
<xsl:param name="test"/>
<xsl:text>false</xsl:text>
</xsl:template>
<!--
Common attributes
-->
<!-- template: name="checkAttributes"
function: check the common XForms attributes and produces
apropriated attributes
parameters: a context node, with the following attributes
@id ()
@required (false)
@relevant (false)
@readOnly (false)
@calc ()
@choices ()
@validate ()
glob. var.: $maxOccursSpecial
output: transformation of attributes
-->
<xsl:template name="checkAttributes">
<!-- copy ID, if any -->
<xsl:if test="string-length(@id) > 0">
<xsl:attribute name="id">
<xsl:value-of select="@id"/>
</xsl:attribute>
</xsl:if>
<!-- check if this element is optional, it is optional,
if: it's not relevant or it's not required, or it's
minOccurs = 0 -->
<xsl:choose>
<xsl:when test="@relevant='true'">
<xsl:choose>
<xsl:when test="@required='true'">
<xsl:if test="not(@minOccurs='1')">
<!-- check if $minOccurs if a non negative integer -->
<xsl:variable name="nn">
<xsl:call-template name="checkNonNegInt">
<xsl:with-param name="test">
<xsl:value-of select="@minOccurs"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$nn='false'">
<!-- if it's not, the element needs not to occur in
a Schema -->
<xsl:if test="not(name(..)='model' or name(..)='simple')">
<!-- root elements must not have minOccurs -->
<xsl:attribute name="minOccurs">foo0</xsl:attribute>
</xsl:if>
<!-- but preserve it in the xfm namespace -->
<xsl:attribute name="xfm:minOccurs">
<xsl:value-of select="@minOccurs"/>
</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<!-- minOccurs is a non negative Integer, so we can
have the Schema follow the restriction -->
<xsl:if test="not(name(..)='model' or name(..)='simple')">
<xsl:attribute name="minOccurs">
<xsl:value-of select="@minOccurs"/>
</xsl:attribute>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
<!-- there is no else, because the default for minOccurs
in Schemas is 1 -->
</xsl:if>
</xsl:when>
<xsl:otherwise>
<xsl:if test="not(name(..)='model' or name(..)='simple')">
<!-- root elements must not have minOccurs -->
<xsl:attribute name="minOccurs">foo10</xsl:attribute>
</xsl:if>
<!-- preserver required and minOccirs in xfm namespace -->
<xsl:attribute name="xfm:required">
<xsl:value-of select="@required"/>
</xsl:attribute>
<xsl:attribute name="xfm:minOccurs">
<xsl:value-of select="@minOccurs"/>
</xsl:attribute>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:if test="not(name(..)='model' or name(..)='simple')">
<!-- root elements must not have minOccurs -->
<xsl:attribute name="minOccurs">foo20</xsl:attribute>
</xsl:if>
<!-- preserver relevant, required and minOccurs in xfm
namespace -->
<xsl:if test="not(string-length(@relevant)=0 or @relevant='false')">
<xsl:attribute name="xfm:relevant">
<xsl:value-of select="@relevant"/>
</xsl:attribute>
</xsl:if>
<xsl:if test="not(string-length(@required)=0 or @required='false')">
<xsl:attribute name="xfm:required">
<xsl:value-of select="@required"/>
</xsl:attribute>
</xsl:if>
<xsl:if test="not(string-length(@minOccurs)=0 or @minOccurs='1')">
<xsl:attribute name="xfm:minOccurs">
<xsl:value-of select="@minOccurs"/>
</xsl:attribute>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
<!-- check maxOccurs, it can be: "unbounded", "1" (default), a none
negative integer, or an expression -->
<xsl:choose>
<xsl:when test="@maxOccurs=$maxOccursSpecial">
<!-- copy it into the Schema -->
<xsl:if test="not(name(..)='model' or name(..)='simple')">
<!-- root elements must not have maxOccurs -->
<xsl:attribute name="maxOccurs">unbounded</xsl:attribute>
</xsl:if>
</xsl:when>
<xsl:when test="not(@maxOccurs='1')">
<!-- check if $maxOccurs if a non negative integer -->
<xsl:variable name="nn">
<xsl:call-template name="checkNonNegInt">
<xsl:with-param name="test">
<xsl:value-of select="@maxOccurs"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$nn='false'">
<!-- if it's not, the element may occur an unlimited number
of times in a Schema -->
<xsl:if test="not(name(..)='model' or name(..)='simple')">
<!-- root elements must not have maxOccurs -->
<xsl:attribute name="maxOccurs">unbounded</xsl:attribute>
</xsl:if>
<!-- but preserve maxOccurs it in the xfm namespace -->
<xsl:if test="not(@maxOccurs='unbounded')">
<xsl:attribute name="xfm:maxOccurs">
<xsl:value-of select="@maxOccurs"/>
</xsl:attribute>
</xsl:if>
</xsl:when>
<xsl:otherwise>
<!-- maxOccurs is a non negative Integer, so we can
have the Schema follow the restriction -->
<xsl:if test="not(name(..)='model' or name(..)='simple')">
<!-- root elements must not have maxOccurs -->
<xsl:attribute name="maxOccurs">
<xsl:value-of select="@maxOccurs"/>
</xsl:attribute>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<!-- there is no otherwise, because the default for maxOccurs in
Schemas is 1 -->
</xsl:choose>
<!-- readOnly is of general interest, but can only be mapped into the
xfm namespace -->
<xsl:if test="not(string-length(@readOnly)=0 or @readOnly='false')">
<xsl:attribute name="xfm:readOnly">
<xsl:value-of select="@readOnly"/>
</xsl:attribute>
</xsl:if>
<!-- validate is of general interest, but can only be mapped into the
xfm namespace -->
<xsl:if test="not(string-length(@validate)=0 or @validate='true')">
<xsl:attribute name="xfm:validate">
<xsl:value-of select="@validate"/>
</xsl:attribute>
</xsl:if>
<!-- calc is of general interest, but can only be mapped into the
xfm namespace -->
<xsl:if test="string-length(@calc) > 0">
<xsl:attribute name="xfm:calc">
<xsl:value-of select="@calc"/>
</xsl:attribute>
</xsl:if>
<!-- choices is of general interest, but can only be mapped into the
xfm namespace -->
<xsl:if test="string-length(@choices) > 0">
<xsl:attribute name="xfm:choices">
<xsl:value-of select="@choices"/>
</xsl:attribute>
</xsl:if>
</xsl:template>
</xsl:transform>
|