I am trying to make a xsl in order to convert a relaxNG schema into a web html form.
It still lacks a lot of things, and I didn't put the javascript code in it(not difficult). I think it is a good start.
Here is my work :
<xsl:template match="rng:start">
<xsl:apply-templates>
<xsl:with-param name="pathInXml" select="''"/>
</xsl:apply-templates>
</xsl:template>
<!-- with a ref element we need to look for its define -->
<xsl:template match="rng:ref[@name]">
<xsl:param name="pathInXml"/>
<xsl:param name="nodeName" select="@name"/>
<xsl:apply-templates select="/rng:grammar/rng:define[@name=$nodeName]">
<xsl:with-param name="pathInXml" select="$pathInXml"/>
</xsl:apply-templates>
</xsl:template>
<!-- with the three next elements, we just make a recursion on
the children, passing the parameter pathInXml -->
<xsl:template match="rng:define[@name]">
<xsl:param name="pathInXml"/>
<xsl:apply-templates select="*">
<xsl:with-param name="pathInXml" select="$pathInXml"/>
</xsl:apply-templates>
</xsl:template>
<!-- with an optional element we add a comment around its children -->
<xsl:template match="rng:optional">
<xsl:param name="pathInXml"/>
<xsl:call-template name="indent">
<xsl:with-param name="pathInXML" select="$pathInXml"/>
</xsl:call-template>
The following parameter(s) is(are) optional : {
<br/>
<xsl:apply-templates select="*">
<xsl:with-param name="pathInXml" select="$pathInXml"/>
</xsl:apply-templates>
<xsl:call-template name="indent">
<xsl:with-param name="pathInXML" select="$pathInXml"/>
</xsl:call-template>
}
<br/>
</xsl:template>
<xsl:template match="rng:zeroOrMore|rng:oneOrMore">
<xsl:param name="pathInXml"/>
<xsl:call-template name="indent">
<xsl:with-param name="pathInXML" select="$pathInXml"/>
</xsl:call-template>
<input type="button" value="+" onclick="addOne(this)"/>
<div>
<xsl:apply-templates select="*">
<xsl:with-param name="pathInXml" select="$pathInXml"/>
</xsl:apply-templates>
</div>
<br/>
</xsl:template>
<!-- with an element markup, we make a recursion on the children,
adding the current element to the parameter pathInXml -->
<xsl:template match="rng:element[@name]">
<xsl:param name="pathInXml"/>
<xsl:param name="elementName" select="@name"/>
<xsl:call-template name="indent">
<xsl:with-param name="pathInXML" select="$pathInXml"/>
</xsl:call-template>
<xsl:value-of select="$elementName"/>
<br/>
<xsl:apply-templates select="*">
<xsl:with-param name="pathInXml" select="concat($pathInXml,'/',$elementName)"/>
</xsl:apply-templates>
<br/>
</xsl:template>
<!-- a choice element will create a dropdown list of choices : -->
<xsl:template match="rng:choice">
<xsl:param name="pathInXml"/>
<br/>
<xsl:call-template name="indent">
<xsl:with-param name="pathInXML" select="$pathInXml"/>
</xsl:call-template>
<select style="height: 20px; width: 250px"
onchange="moveOptionContent(this)">
<xsl:apply-templates select="rng:ref[@name]" mode="choice">
<xsl:with-param name="pathInXml" select="$pathInXml"/>
</xsl:apply-templates>
</select>
<xsl:apply-templates select="rng:ref[@name]" mode="addHidden">
<xsl:with-param name="pathInXml" select="$pathInXml"/>
</xsl:apply-templates>
<br/>
</xsl:template>
<!-- with a ref element in the mode choice, it fills the select element of the choice
with the different ref values -->
<xsl:template match="rng:ref[@name]" mode="choice">
<xsl:param name="pathInXml"/>
<xsl:param name="nodeName" select="@name"/>
<option value="{$nodeName}" name="{$pathInXml}/{$nodeName}">
<xsl:value-of select="$nodeName"/>
</option>
</xsl:template>
<xsl:template match="rng:ref[@name]" mode="addHidden">
<xsl:param name="pathInXml"/>
<xsl:param name="nodeName" select="@name"/>
<div name="{$nodeName}" style="display: none">
<xsl:apply-templates select="/rng:grammar/rng:define[@name=$nodeName]">
<xsl:with-param name="pathInXml" select="$pathInXml"/>
</xsl:apply-templates>
</div>
</xsl:template>
<!-- with an attribute element, we wait for a data markup -->
<xsl:template match="rng:attribute[@name]">
<xsl:param name="pathInXml"/>
<xsl:param name="attributeName" select="@name"/>
<xsl:call-template name="indent">
<xsl:with-param name="pathInXML" select="$pathInXml"/>
</xsl:call-template>
<xsl:value-of select="$attributeName"/> :
<xsl:apply-templates select="rng:data">
<xsl:with-param name="attributeName" select="$attributeName"/>
<xsl:with-param name="pathInXml" select="$pathInXml"/>
</xsl:apply-templates>
<br/>
<xsl:apply-templates select="a:documentation"/>
</xsl:template>
<!-- those nodes are end of the tree : -->
<xsl:template match="a:documentation">
<xsl:copy-of select="current()"/>
<br/>
</xsl:template>
<!-- At the end of the tree, we add :attributeName to the pathInXml and make the
input markup -->
<xsl:template match="rng:data">
<xsl:param name="pathInXml"/>
<xsl:param name="attributeName"/>
<input type="text" name="{$pathInXml}/@{$attributeName}"/>
</xsl:template>
<!-- In order to indent, we split the pathInXML with the / separator and we call
the function recursively until there is no separator left -->
<xsl:template name="indent">
<xsl:param name="pathInXML"/>
<xsl:if test="contains($pathInXML, '/')">
<xsl:call-template name="indent">
<xsl:with-param name="pathInXML" select="substring-after($pathInXML,'/')"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
|