XML Schema / XML / XSLT 综合使用之电子表单

XML Schema / XML / XSLT 综合运用之电子表单

此为末学在开发OA系统中针对电子表单功能块所进行的实验性方案,因此前对XML虽有所了解,但运用并不熟练,幸于W3chool 等网站受益颇多,耗费一周始才完成,古人有云“滴水之恩,当以涌泉相报”,故将此拙作奉献于广大软件技术爱好者,虽不敢以涌泉而自诩,但于初学或有所益也。


以下张贴内容版权开放,转载请注明出处。


电子表单内容由XML文件来承载,在具体创建表单时,因怕对格式书写有误,故用XML Schema以约束之,而用户在系统中填报表单所面对的应是Web页面,故又以XSLT加以转换,所有关联文件分贴如下:

 

XML模板文件: form.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.w3school.com.cn/eForm"
	elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"
	xmlns:ef="http://www.w3school.com.cn/eForm">

	<xs:attributeGroup name="fieldAttributeGroup">
		<xs:attribute name="id" type="xs:Name" use="required" />
		<xs:attribute name="label" type="xs:token" use="required" />
		<xs:attribute name="require" type="xs:boolean" use="optional" />
		<xs:attribute name="description" type="xs:token" use="optional" />
	</xs:attributeGroup>

	<xs:complexType name="stringField">
		<xs:attributeGroup ref="ef:fieldAttributeGroup" />
		<xs:attribute name="value" type="xs:token" />
	</xs:complexType>

	<xs:complexType name="textField">
		<xs:simpleContent>
			<xs:extension base="xs:string">
				<xs:attributeGroup ref="ef:fieldAttributeGroup" />
			</xs:extension>
		</xs:simpleContent>
	</xs:complexType>

	<xs:complexType name="numbleField">
		<xs:attributeGroup ref="ef:fieldAttributeGroup" />
		<xs:attribute name="value" type="xs:decimal" />
	</xs:complexType>

	<xs:complexType name="dateField">
		<xs:attributeGroup ref="ef:fieldAttributeGroup" />
		<xs:attribute name="value" type="xs:date" />
	</xs:complexType>

	<xs:complexType name="singleChoiceField">
		<xs:all>
			<xs:element name="options" type="ef:options" />
		</xs:all>
		<xs:attributeGroup ref="ef:fieldAttributeGroup" />
	</xs:complexType>

	<xs:complexType name="multipleChoiceField">
		<xs:all>
			<xs:element name="options" type="ef:options" />
		</xs:all>
		<xs:attributeGroup ref="ef:fieldAttributeGroup" />
	</xs:complexType>

	<xs:complexType name="options">
		<xs:choice minOccurs="2" maxOccurs="unbounded">
			<xs:element name="option" type="ef:option" />
		</xs:choice>

	</xs:complexType>

	<xs:complexType name="option">
		<xs:simpleContent>
			<xs:extension base="xs:normalizedString">
				<xs:attribute name="checked" type="xs:boolean" />
			</xs:extension>
		</xs:simpleContent>
	</xs:complexType>

	<xs:complexType name="group">
		<xs:group ref="ef:field" minOccurs="1" maxOccurs="unbounded" />
		<xs:attribute name="label" type="xs:token" use="required" />
	</xs:complexType>

	<xs:group name="field">
		<xs:choice>
			<xs:element name="dateField" type="ef:dateField" nillable="true" />
			<xs:element name="multipleChoiceField" type="ef:multipleChoiceField" />
			<xs:element name="numbleField" type="ef:numbleField"
				nillable="true" />
			<xs:element name="singleChoiceField" type="ef:singleChoiceField" />
			<xs:element name="stringField" type="ef:stringField"
				nillable="true" />
			<xs:element name="textField" type="ef:textField" nillable="true" />
			<xs:element name="group" type="ef:group" />
		</xs:choice>
	</xs:group>

	<xs:element name="form">
		<xs:complexType>
			<xs:group ref="ef:field" minOccurs="1" maxOccurs="unbounded" />
		</xs:complexType>
		<xs:key name="ID">
			<xs:selector
				xpath=".//ef:dateField | .//ef:multipleChoiceField | .//ef:numbleField | .//ef:singleChoiceField | .//ef:stringField | .//ef:textField" />
			<xs:field xpath="@id" />
		</xs:key>
	</xs:element>

</xs:schema>

 

xml示例文件:sample.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="formEdit.xsl"?>
<ef:form xmlns:ef="http://www.w3school.com.cn/eForm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.w3school.com.cn/eForm form.xsd ">
	<ef:multipleChoiceField label="多选1" id="duoxuan1" description="描述多选字段">
		<ef:options>
			<ef:option>选项1</ef:option>
			<ef:option checked="true">选项2</ef:option>
			<ef:option>选项3</ef:option>
		</ef:options>
	</ef:multipleChoiceField>
	<ef:group label="组1">
		<ef:dateField label="时间" id="shijian" description="描述时间字段"/>
		<ef:numbleField label="数字" id="shuzi" value="2"/>
	</ef:group>
	<ef:dateField label="时间1" id="shijian1" value="2009-01-01" />
	<ef:dateField label="时间2" id="shijian2" />
	<ef:stringField label="字符串1" id="zifuchuan" value="默认字符串"/>
	<ef:textField label="常字符串" id="DD">
	你好
	我很好
	</ef:textField>
	<ef:group label="组2">
		<ef:singleChoiceField label="单选" id="danxuan">
			<ef:options>
				<ef:option>选项1</ef:option>
				<ef:option>选项2</ef:option>
				<ef:option>选项3</ef:option>
			</ef:options>
		</ef:singleChoiceField>
	</ef:group>
</ef:form>

 

xslt转换文件:formEdit.xsl

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ef="http://www.w3school.com.cn/eForm">
	<xsl:template match="/">
		<html>
			<head>
				<title>显示表单</title>
				<link type="text/css" rel="stylesheet" href="ef.css" />
			</head>
			<body>
				<xsl:apply-templates />
			</body>
		</html>
	</xsl:template>

	<!-- 组模板 -->
	<xsl:template match="ef:group">
		<fieldSet class="ef-group">
			<legend>
				<xsl:value-of select="@label"></xsl:value-of>
			</legend>
			<xsl:apply-templates />
		</fieldSet>
	</xsl:template>

	<!-- 日期字段模板 -->
	<xsl:template match="ef:dateField">
		<div class="ef-date-field">
			<xsl:call-template name="fieldLabel" />
			<div class="ef-input-control">
				<input type="text">
					<xsl:call-template name="inputControlAttribute" />
				</input>
			</div>
		</div>
	</xsl:template>

	<!-- input输入控件属性模板 -->
	<xsl:template name="inputControlAttribute">
		<xsl:attribute name="id">
			<xsl:value-of select="@id" />
		</xsl:attribute>
		<xsl:attribute name="name">
			<xsl:value-of select="@id" />
		</xsl:attribute>
		<xsl:attribute name="value">
			<xsl:value-of select="@value" />
		</xsl:attribute>
	</xsl:template>

	<!-- 字段标签模板 -->
	<xsl:template name="fieldLabel">
		<label class="ef-field-label">
			<xsl:attribute name="for">
				<xsl:value-of select="@id" />
			</xsl:attribute>
			<xsl:attribute name="title">
				<xsl:value-of select="@description" />
			</xsl:attribute>
			<xsl:value-of select="@label" />
		</label>
	</xsl:template>

	<!-- 选项属性模板 -->
	<xsl:template name="choiceOptionAttribute">
		<xsl:param name="choiceFieldId" />
		<xsl:attribute name="id">
			<xsl:value-of select="$choiceFieldId" />
			<xsl:number />
		</xsl:attribute>
		<xsl:attribute name="name">
			<xsl:value-of select="$choiceFieldId" />
		</xsl:attribute>
		<xsl:attribute name="value">
			<xsl:choose>
				<xsl:when test="@value">
					<xsl:value-of select="@value" />
				</xsl:when>
				<xsl:otherwise>
					<xsl:value-of select="text()" />
				</xsl:otherwise>
			</xsl:choose>
		</xsl:attribute>
		<xsl:if test="@checked = 'true'">
			<xsl:attribute name="checked"> 
				<xsl:value-of select="'checked'" /> 
			</xsl:attribute>
		</xsl:if>
	</xsl:template>

	<!-- 选项标签模板 -->
	<xsl:template name="optionLabel">
		<xsl:param name="choiceFieldId" />
		<label>
			<xsl:attribute name="for">
				<xsl:value-of select="$choiceFieldId" />
				<xsl:number />
			</xsl:attribute>
			<xsl:value-of select="text()" />
		</label>
	</xsl:template>

	<!-- 多选字段模板 -->
	<xsl:template match="ef:multipleChoiceField">
		<xsl:variable name="choiceFieldId" select="@id" />
		<div class="ef-multiple-choice-field">
			<xsl:call-template name="fieldLabel" />
			<div class="ef-checkbox-group">
				<xsl:for-each select="ef:options/ef:option">
					<div class="ef-checkbox">
						<input type="checkbox">
							<xsl:call-template name="choiceOptionAttribute">
								<xsl:with-param name="choiceFieldId" select="$choiceFieldId" />
							</xsl:call-template>
						</input>
						<xsl:call-template name="optionLabel">
							<xsl:with-param name="choiceFieldId" select="$choiceFieldId" />
						</xsl:call-template>
					</div>
				</xsl:for-each>
			</div>
		</div>
	</xsl:template>

	<!-- 数字字段模板 -->
	<xsl:template match="ef:numbleField">
		<div class="ef-numble-field">
			<xsl:call-template name="fieldLabel" />
			<div class="ef-input-control">
				<input type="text">
					<xsl:call-template name="inputControlAttribute" />
				</input>
			</div>
		</div>
	</xsl:template>

	<!-- 单选字段模板 -->
	<xsl:template match="ef:singleChoiceField">
		<xsl:variable name="choiceFieldId" select="@id" />
		<div class="ef-single-choice-field">
			<xsl:call-template name="fieldLabel" />
			<div class="ef-radio-group">
				<xsl:for-each select="ef:options/ef:option">
					<div class="ef-radio">
						<input type="radio">
							<xsl:call-template name="choiceOptionAttribute">
								<xsl:with-param name="choiceFieldId" select="$choiceFieldId" />
							</xsl:call-template>
						</input>
						<xsl:call-template name="optionLabel">
							<xsl:with-param name="choiceFieldId" select="$choiceFieldId" />
						</xsl:call-template>
					</div>
				</xsl:for-each>
			</div>
		</div>
	</xsl:template>

	<!-- 字符串字段模板 -->
	<xsl:template match="ef:stringField">
		<div class="ef-string-field">
			<xsl:call-template name="fieldLabel" />
			<div class="ef-input-control">
				<input type="text">
					<xsl:call-template name="inputControlAttribute" />
				</input>
			</div>
		</div>
	</xsl:template>

	<!-- 长文本字段模板 -->
	<xsl:template match="ef:textField">
		<div class="ef-text-field">
			<xsl:call-template name="fieldLabel" />
			<div class="ef-textarea-control">
				<textarea>
					<xsl:attribute name="id">
						<xsl:value-of select="@id" />
					</xsl:attribute>
					<xsl:attribute name="name">
						<xsl:value-of select="@id" />
					</xsl:attribute>
					<xsl:value-of select="text()" />
				</textarea>
			</div>
		</div>
	</xsl:template>

</xsl:stylesheet>

 

最后与页面显示有关的css样式表文件:ef.css

@CHARSET "UTF-8";

.ef-group,.ef-date-field,.ef-multiple-choice-field,.ef-numble-field,.ef-single-choice-field,.ef-string-field,.ef-text-field
	{
	margin: 5px;
	width: 100%;
}

.ef-field-label {
	float: left;
	width: 100px;
	font-weight: bold;
}

.ef-checkbox,.ef-radio {
	float: left;
	margin-right: 10px;
}
 

最终效果如下图所示:

XML Schema / XML / XSLT 综合使用之电子表单

1 楼 mike507 2010-08-30  
能不能把formEdit.xsl 文件也发布出来呢?这样不是更有利于大家学习吗?
2 楼 lizhengjun 2010-09-14  
已经是全部都贴出来了!