結合元素和屬性的定義分析Schema的幾種設計方案

林竟發表於2013-11-30

Schema的幾種設計方案

1.Russian Doll 俄羅斯玩偶

只有一個根元素,通過巢狀的方式完成編寫

優點:結構清晰,根元素只有一個

缺點:元素無法重用

books.xsd

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" 
		targetNamespace="http://www.example.org/02"
		xmlns:tns="http://www.example.org/02" 
		elementFormDefault="qualified">
<!-- 
元素的定義(元素及子元素)

屬性的定義,在sequence之後

Russian Doll
	只有一個根元素,通過巢狀的方式完成編寫
	優點:結構清晰,根元素只有一個
	缺點:元素無法重用
 -->
	<element name="books">
		<complexType>
			<!-- sequence: 子元素按照順序出現 -->
			<sequence maxOccurs="unbounded">
				<element name="book">
					<complexType>
						<sequence minOccurs="1" maxOccurs="unbounded">
							<element name="title" type="string" />
							<element name="content" type="string" />
							<!-- choice: 多個子元素中選擇一個 -->
							<choice>
								<element name="author" type="string" />
								<element name="authors">
									<complexType>
										<!-- all: 子元素出現的順序任意,但每個子元素可出現零次或一次 -->
										<all>
											<element name="author" type="string" />
										</all>
										<!-- 如果有多個author,即author子元素出現多次,改用sequence標籤
										<sequence maxOccurs="3">
											<element name="author" type="string" />
										</sequence> -->
									</complexType>
								</element>
							</choice>
						</sequence>
						<!-- book元素的屬性,屬性的定義,在sequence之後 -->
						<attribute name="id" type="int" use="required" />
					</complexType>
				</element>
			</sequence>
		</complexType>
	</element>
</schema>

對應的books_1.xml(注意在eclipse中引入對應的xml catalog)

<?xml version="1.0" encoding="UTF-8"?>
<book:books xmlns:book="http://www.example.org/02"
	  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	  xsi:noNamespaceSchemaLocation="02.xsd">

	<book:book id="1">
		<book:title>Java in action</book:title>
		<book:content>java is good</book:content>
		<book:author>Bruce</book:author>
	</book:book>
	<book:book id="2">
		<book:title>SOA in action</book:title>
		<book:content>soa is difficult</book:content>
		<book:authors>
			<book:author>Jack</book:author>
			<book:author>Mike</book:author>
		</book:authors>
	</book:book>
</book:books>

因為引入books.xsd名稱空間的時候加了字首,xmlns:book=http://www.example.org/02,所以對於books.xsd中元素的引用都需要加入字首book。

2.Salami Slice 臘腸切片

優點:能夠進行最大化的重用

缺點:根元素不清晰

<?xml version="1.0" encoding="UTF-8"?>
<!-- 
Salami Slice
	優點:能夠進行最大化的重用
	缺點:根元素不清晰
 -->
<schema xmlns="http://www.w3.org/2001/XMLSchema" 
		targetNamespace="http://www.example.org/03"
		xmlns:tns="http://www.example.org/03" 
		elementFormDefault="qualified">
		
		<element name="book" type="tns:bookType" />
		<element name="id" type="int" />
		<element name="title" type="string" />
		<element name="content" type="string" />
		
		<!-- 複雜型別 -->
		<complexType name="bookType">
			<sequence>
				<element ref="tns:id" />
				<element ref="tns:title" />
				<element ref="tns:content" />
			</sequence>
		</complexType>
</schema>

3.Venetian Blind 百頁窗

一個根節點

通過simpleType完成重用

<?xml version="1.0" encoding="UTF-8"?>
<!-- 
Venetian Blind
	一個根節點
	通過simpleType完成重用
 -->
<schema xmlns="http://www.w3.org/2001/XMLSchema" 
		targetNamespace="http://www.example.org/04"
		xmlns:tns="http://www.example.org/04" 
		elementFormDefault="qualified">
		
		<element name="person" type="tns:personType" />
		
		<!-- 複雜型別 -->
		<complexType name="personType">
			<sequence>
				<element name="name" type="string" />
				<element name="age" type="tns:ageType" />
				<!-- 將sex定義為子元素 -->
				<!--<element name="sex" type="tns:sexType" /> -->
				<element name="email" type="tns:emailType" />
			</sequence>
			<!-- 將sex定義為屬性 -->
			<attribute name="sex" type="tns:sexType" />
		</complexType>
		
		<!-- 簡單型別,通過對簡單型別的描述,完成重用。 
		(可定義不同的element,type為某個簡單型別,完成重用)-->
		<simpleType name="ageType">
			<restriction base="int">
				<minInclusive value="1" />
				<maxExclusive value="300" />
			</restriction>
		</simpleType>
		
		<simpleType name="sexType">
			<restriction base="string">
				<enumeration value="男" />
				<enumeration value="女" />
			</restriction>
		</simpleType>
		
		<simpleType name="emailType">
			<restriction base="string">
				<pattern value="\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*" />
				<minLength value="6" />
				<maxLength value="255" />
			</restriction>
		</simpleType>		
</schema>

對應的person_1.xml

<?xml version="1.0" encoding="UTF-8"?>
<person xmlns="http://www.example.org/04"
	  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	  xsi:schemaLocation="http://www.example.org/04"
	  sex="女">
	  <name>姚雙雙</name>
	  <age>25</age>
	  <email>yaoshuangg@163.com</email>
</person>


以上是schema的幾種設計方案,通常使用第三種方案,即Venetian Blind百頁窗式。

綜上,元素的定義採用<element>標籤;通過<complexType>定義子元素及子元素的順序、數量等;通過<simpleType>定義多種簡單型別,完成重用;屬性的定義在<sequence>之後(,<complexType>之中)。

相關文章