XML學習筆記7——XSD實例


  在前面的XSD筆記中,基本上是以數據類型為主線來寫的,而在我的實際開發過程中,是先設計好了XML的結構(元素、屬性),並寫好了一份示例,然后再反過來寫XSD文件(在工具生成的基礎上修改),也就是說,是以XML結構為主線的。而我在學習XSD的時候,則是以能否看懂spring-beans-3.2.xsd這個文件來檢測自己,我的想法很簡單,這個文件已經夠復雜——對我來說——如果能夠看懂這個文件,那基本上已經夠我用的了,倘若實際開發的時候遇到超出這個范圍的,那到時候再找相關資料學習也不晚。

一、為XML結構編寫相應XSD片段

1、定義一個沒有屬性也沒有內容的元素——沒有屬性的空元素:

<xs:element name="emptyElement">
  <xs:complexType>
    <!--既然XML文件中所有能出現的元素和屬性都必須在XSD中出現,那么什么都沒定義的意思就是什么都不能出現了-->
  </xs:complexType>
</xs:element>

2、定義一個沒有內容的元素,但是這個元素有兩個屬性,一個必須的id屬性,一個可選的name屬性:

<xs:element name="emptyElementWithAttribute">
  <xs:complexType>
    <xs:attribute name="id" type="xs:ID" use="required"/>
    <xs:attribute name="name" type="xs:NMTOKEN" default="未定義"/>
  </xs:complexType>
</xs:element>

3、定義有內容但是沒有屬性的元素——簡單元素

<!--1.使用內建類型,內容為字符串-->
<xs:element name="simpleElement1" type="xs:string"/>
<!--2.使用約束派生,內容為長度在6至16之間的字符串-->
<xs:element name="simpleElement2">
  <xs:simpleType>
    <xs:restriction base="xs:string">
      <xs:annotation>
        <xs:documentation><![CDATA[
         長度大於或等於6,小於或等於16的字符串
        ]]></xs:documentation>
      </xs:annotation>
      <xs:minLength value="6"/>
      <xs:maxLength value="16"/>
    </xs:restriction>
  </xs:simpleType>
</xs:element>
<!--3.使用列表派生,內容為已經存在的一個或多個ID類型數據的列表-->
<xs:element name="simpleElement3">
  <xs:simpleType>
    <xs:list itemType="xs:IDREF"/>
  </xs:simpleType>
</xs:element>
<!--4.使用聯合派生,內容可以是整型,也可以是NMTOKEN類型-->
<xs:element name="simpleElement4">
  <xs:simpleType>
    <xs:union memberTypes="xs:int xs:NMTOKEN"/>
  </xs:simpleType>
</xs:element>

4、定義只包含子元素的元素,不能包含內容,但可以包含屬性

<!-- 空類型 -->
<xs:complexType name="emptyType">
</xs:complexType>
<!-- 表類別類型(簡單枚舉類型) -->
<xs:simpleType name="tableTypeType">
  <xs:restriction base="xs:string">
      <xs:enumeration value="系統表"/>
      <xs:enumeration value="參數表"/>
      <xs:enumeration value="數據表"/>
  </xs:restriction>
</xs:simpleType>
<!-- 名稱類型(2-30位的字符串) -->
<xs:simpleType name="nameType">
  <xs:restriction base="xs:NCName">
      <xs:minLength value="2"/>
      <xs:maxLength value="30"/>
  </xs:restriction>
</xs:simpleType>
<!-- 注釋類型(2-1024位的字符串) -->
<xs:simpleType name="commentType">
  <xs:restriction base="xs:string">
      <xs:minLength value="2"/>
      <xs:maxLength value="1024"/>
  </xs:restriction>
</xs:simpleType>
<!-- 字段元素(含屬性不含內容元素)-->
<xs:element name="field">
  <xs:complexType>
      <xs:complexContent>
          <xs:extension base="emptyType">
              <xs:attribute name="fieldName" type="nameType" use="required"/>
              <xs:attribute name="dataType" type="xs:NCName" use="required"/>
              <xs:attribute name="length" type="xs:int" use="optional"/>
              <xs:attribute name="comment" type="commentType" use="optional"/>
          </xs:extension>
      </xs:complexContent>
  </xs:complexType>
</xs:element>
<!-- 表元素(含屬性和子元素的元素) -->
<xs:element name="table">
    <xs:complexType>
        <xs:sequence>
            <xs:element minOccurs="1" maxOccurs="unbounded" ref="field" />
        </xs:sequence>
        <xs:attribute name="tableName" type="nameType" use="required"/>
        <xs:attribute name="tableType" type="tableTypeType" use="required"/>
        <xs:attribute name="comment" type="commentType" use="optional"/>
    </xs:complexType>
    <xs:key name="fieldKey">
      <xs:selector xpath="field"/>
      <xs:field xpath="@fieldName"/>
    </xs:key>
</xs:element>

這里有一個疑問,在最后定義的時候,我添加了一個key約束,本意是想在一個table元素里所有的field元素中fieldName屬性必須存在且唯一,但是我在實際配置XML文檔時,在兩個field中相同的fieldName也沒有報錯,不知道是哪里寫錯了。

5、定義既包含子元素又包含內容的混合元素,同時也可以擁有屬性

比如將上面例子中<table>元素修改為可以包括內容,可以在<xs:complexType>加一個mixed="true"屬性:

<!-- 表元素(含屬性、內容和子元素的元素) -->
<xs:element name="table">
    <xs:complexType mixed="true">
        <xs:sequence>
            <xs:element minOccurs="1" maxOccurs="unbounded" ref="field" />
        </xs:sequence>
        <xs:attribute name="tableName" type="nameType" use="required"/>
        <xs:attribute name="tableType" type="tableTypeType" use="required"/>
        <xs:attribute name="comment" type="commentType" use="optional"/>
    </xs:complexType>
</xs:element>

二、spring-beans-3.2.xsd

  我將這個文件放在這里,每次看的時候都能夠檢測一下(其中以<annotation>元素描述的注釋內容去掉了,並簡單修改了一小部分寫法):

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://www.springframework.org/schema/beans">
    
    <!--導入命名空間,並保持原命名空間-->
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
    
    <!--定義抽象的id標識類型,供后文引用,而不能直接在XML中使用-->
    <xsd:complexType name="identifiedType" abstract="true">
        <xsd:attribute name="id" type="xsd:string"/>
    </xsd:complexType>

        <!--定義根元素beans,包含子元素的復雜類型元素-->
    <xsd:element name="beans">
        <xsd:complexType>
            <xsd:sequence>
                    <!--首先是描述信息,可以出現,也可以不出現-->
                <xsd:element ref="description" minOccurs="0"/>
                <!--然后是主體部分,這里使用相當於DTD中的 (e1|e2|e3)* 結構實現自由組合的無序元素 -->
                <xsd:choice minOccurs="0" maxOccurs="unbounded">
                    <xsd:element ref="import"/>
                    <xsd:element ref="alias"/>
                    <xsd:element ref="bean"/>
                    <!--除了使用當前XSD文件的元素,還以使用導入的其它XSD文件中定義的元素,不過必須先獲取相應的XSD文件,並做嚴格的校驗-->
                    <xsd:any namespace="##other" processContents="strict" minOccurs="0" maxOccurs="unbounded"/>
                </xsd:choice>
                <!--從這里可以看到,原來beans這個元素還可以嵌套,大體作用相當於import吧,只是import導入的就不是本地的配置,而嵌套的應該還屬於本地的配置(?)-->
                <xsd:element ref="beans" minOccurs="0" maxOccurs="unbounded"/>
            </xsd:sequence>
            <xsd:attribute name="profile" use="optional" type="xsd:string"/>
            <!--對於多個地方都使用的true|false|default,將其定義為一個自定義數據類型,然后再在需要的地方引用-->
            <xsd:attribute name="default-lazy-init" default="default" type="defaultable-boolean"/>
            <xsd:attribute name="default-merge" default="default" type="defaultable-boolean"/>
            <xsd:attribute name="default-autowire" default="default">
                <xsd:simpleType>
                    <!--通過限制定義自動包裝的枚舉類型-->
                    <xsd:restriction base="xsd:NMTOKEN">
                        <xsd:enumeration value="default"/>
                        <xsd:enumeration value="no"/>
                        <xsd:enumeration value="byName"/>
                        <xsd:enumeration value="byType"/>
                        <xsd:enumeration value="constructor"/>
                    </xsd:restriction>
                </xsd:simpleType>
            </xsd:attribute>
            <xsd:attribute name="default-autowire-candidates" type="xsd:string"/>
            <xsd:attribute name="default-init-method" type="xsd:string"/>
            <xsd:attribute name="default-destroy-method" type="xsd:string"/>
            <!--還可以有其它命名空間的屬性,並且不會做強制的檢查-->
            <xsd:anyAttribute namespace="##other" processContents="lax"/>
        </xsd:complexType>
    </xsd:element>

    <!--定義描述信息元素,混合內容元素-->
    <xsd:element name="description">
        <xsd:complexType mixed="true">
            <xsd:choice minOccurs="0" maxOccurs="unbounded"/>
        </xsd:complexType>
    </xsd:element>

    <xsd:element name="import">
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:restriction base="xsd:anyType">
                    <xsd:attribute name="resource" type="xsd:string" use="required"/>
                </xsd:restriction>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>

    <xsd:element name="alias">
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:restriction base="xsd:anyType">
                    <xsd:attribute name="name" type="xsd:string" use="required"/>
                    <xsd:attribute name="alias" type="xsd:string" use="required"/>
                </xsd:restriction>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>

    <xsd:group name="beanElements">
        <xsd:sequence>
            <xsd:element ref="description" minOccurs="0"/>
            <xsd:choice minOccurs="0" maxOccurs="unbounded">
                <xsd:element ref="meta"/>
                <xsd:element ref="constructor-arg"/>
                <xsd:element ref="property"/>
                <xsd:element ref="qualifier"/>
                <xsd:element ref="lookup-method"/>
                <xsd:element ref="replaced-method"/>
                <xsd:any namespace="##other" processContents="strict" minOccurs="0" maxOccurs="unbounded"/>
            </xsd:choice>
        </xsd:sequence>
    </xsd:group>

    <xsd:attributeGroup name="beanAttributes">
        <xsd:attribute name="name" type="xsd:string"/>
        <xsd:attribute name="class" type="xsd:string"/>
        <xsd:attribute name="parent" type="xsd:string"/>
        <xsd:attribute name="scope" type="xsd:string"/>
        <xsd:attribute name="abstract" type="xsd:boolean"/>
        <xsd:attribute name="lazy-init" default="default" type="defaultable-boolean"/>
        <xsd:attribute name="autowire" default="default">
            <xsd:simpleType>
                <xsd:restriction base="xsd:NMTOKEN">
                    <xsd:enumeration value="default"/>
                    <xsd:enumeration value="no"/>
                    <xsd:enumeration value="byName"/>
                    <xsd:enumeration value="byType"/>
                    <xsd:enumeration value="constructor"/>
                </xsd:restriction>
            </xsd:simpleType>
        </xsd:attribute>
        <xsd:attribute name="depends-on" type="xsd:string"/>
        <xsd:attribute name="autowire-candidate" default="default" type="defaultable-boolean"/>
        <xsd:attribute name="primary" type="xsd:boolean"/>
        <xsd:attribute name="init-method" type="xsd:string"/>
        <xsd:attribute name="destroy-method" type="xsd:string"/>
        <xsd:attribute name="factory-method" type="xsd:string"/>
        <xsd:attribute name="factory-bean" type="xsd:string"/>
        <xsd:anyAttribute namespace="##other" processContents="lax"/>
    </xsd:attributeGroup>

    <xsd:element name="meta" type="metaType"/>

    <xsd:complexType name="metaType">
        <xsd:attribute name="key" type="xsd:string" use="required"/>
        <xsd:attribute name="value" type="xsd:string" use="required"/>
    </xsd:complexType>

    <xsd:element name="bean">
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:extension base="identifiedType">
                    <xsd:group ref="beanElements"/>
                    <xsd:attributeGroup ref="beanAttributes"/>
                </xsd:extension>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>

    <xsd:element name="constructor-arg">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element ref="description" minOccurs="0"/>
                <xsd:choice minOccurs="0" maxOccurs="1">
                    <xsd:element ref="bean"/>
                    <xsd:element ref="ref"/>
                    <xsd:element ref="idref"/>
                    <xsd:element ref="value"/>
                    <xsd:element ref="null"/>
                    <xsd:element ref="array"/>
                    <xsd:element ref="list"/>
                    <xsd:element ref="set"/>
                    <xsd:element ref="map"/>
                    <xsd:element ref="props"/>
                    <xsd:any namespace="##other" processContents="strict"/>
                </xsd:choice>
            </xsd:sequence>
            <xsd:attribute name="index" type="xsd:string"/>
            <xsd:attribute name="type" type="xsd:string"/>
            <xsd:attribute name="name" type="xsd:string"/>
            <xsd:attribute name="ref" type="xsd:string"/>
            <xsd:attribute name="value" type="xsd:string"/>
        </xsd:complexType>
    </xsd:element>

    <xsd:element name="property" type="propertyType"/>

    <xsd:element name="qualifier">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element ref="attribute" minOccurs="0" maxOccurs="unbounded"/>
            </xsd:sequence>
            <xsd:attribute name="type" type="xsd:string" default="org.springframework.beans.factory.annotation.Qualifier"/>
            <xsd:attribute name="value" type="xsd:string"/>
        </xsd:complexType>
    </xsd:element>

    <xsd:element name="attribute" type="metaType"/>

    <xsd:element name="lookup-method">
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:restriction base="xsd:anyType">
                    <xsd:attribute name="name" type="xsd:string"/>
                    <xsd:attribute name="bean" type="xsd:string"/>
                </xsd:restriction>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>

    <xsd:element name="replaced-method">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:choice minOccurs="0" maxOccurs="unbounded">
                    <xsd:element ref="arg-type"/>
                </xsd:choice>
            </xsd:sequence>
            <xsd:attribute name="name" type="xsd:string"/>
            <xsd:attribute name="replacer" type="xsd:string"/>
        </xsd:complexType>
    </xsd:element>

    <xsd:element name="arg-type">
        <xsd:complexType mixed="true">
            <xsd:choice minOccurs="0" maxOccurs="unbounded"/>
            <xsd:attribute name="match" type="xsd:string"/>
        </xsd:complexType>
    </xsd:element>

    <xsd:element name="ref">
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:restriction base="xsd:anyType">
                    <xsd:attribute name="bean" type="xsd:string"/>
                    <xsd:attribute name="local" type="xsd:string"/>
                    <xsd:attribute name="parent" type="xsd:string"/>
                </xsd:restriction>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>

    <xsd:element name="idref">
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:restriction base="xsd:anyType">
                    <xsd:attribute name="bean" type="xsd:string"/>
                    <xsd:attribute name="local" type="xsd:string"/>
                </xsd:restriction>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>

    <xsd:element name="value">
        <xsd:complexType mixed="true">
            <xsd:choice minOccurs="0" maxOccurs="unbounded"/>
            <xsd:attribute name="type" type="xsd:string"/>
        </xsd:complexType>
    </xsd:element>

    <xsd:element name="null">
        <xsd:complexType mixed="true">
            <xsd:choice minOccurs="0" maxOccurs="unbounded"/>
        </xsd:complexType>
    </xsd:element>

    <!-- Collection Elements -->
    <xsd:group name="collectionElements">
        <xsd:sequence>
            <xsd:element ref="description" minOccurs="0"/>
            <xsd:choice minOccurs="0" maxOccurs="unbounded">
                <xsd:element ref="bean"/>
                <xsd:element ref="ref"/>
                <xsd:element ref="idref"/>
                <xsd:element ref="value"/>
                <xsd:element ref="null"/>
                <xsd:element ref="array"/>
                <xsd:element ref="list"/>
                <xsd:element ref="set"/>
                <xsd:element ref="map"/>
                <xsd:element ref="props"/>
                <xsd:any namespace="##other" processContents="strict" minOccurs="0" maxOccurs="unbounded"/>
            </xsd:choice>
        </xsd:sequence>
    </xsd:group>

    <xsd:element name="array">
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:extension base="listOrSetType">
                    <xsd:attribute name="merge" default="default" type="defaultable-boolean"/>
                </xsd:extension>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>

    <xsd:element name="list">
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:extension base="listOrSetType">
                    <xsd:attribute name="merge" default="default" type="defaultable-boolean"/>
                </xsd:extension>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>

    <xsd:element name="set">
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:extension base="listOrSetType">
                    <xsd:attribute name="merge" default="default" type="defaultable-boolean"/>
                </xsd:extension>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>

    <xsd:element name="map">
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:extension base="mapType">
                    <xsd:attribute name="merge" default="default" type="defaultable-boolean"/>
                </xsd:extension>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>

    <xsd:element name="entry" type="entryType"/>

    <xsd:element name="props">
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:extension base="propsType">
                    <xsd:attribute name="merge" default="default" type="defaultable-boolean"/>
                </xsd:extension>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>

    <xsd:element name="key">
        <xsd:complexType>
            <xsd:group ref="collectionElements"/>
        </xsd:complexType>
    </xsd:element>

    <xsd:element name="prop">
        <xsd:complexType mixed="true">
            <xsd:choice minOccurs="0" maxOccurs="unbounded"/>
            <xsd:attribute name="key" type="xsd:string" use="required"/>
        </xsd:complexType>
    </xsd:element>

    <xsd:complexType name="propertyType">
        <xsd:sequence>
            <xsd:element ref="description" minOccurs="0"/>
            <xsd:choice minOccurs="0" maxOccurs="1">
                <xsd:element ref="meta"/>
                <xsd:element ref="bean"/>
                <xsd:element ref="ref"/>
                <xsd:element ref="idref"/>
                <xsd:element ref="value"/>
                <xsd:element ref="null"/>
                <xsd:element ref="array"/>
                <xsd:element ref="list"/>
                <xsd:element ref="set"/>
                <xsd:element ref="map"/>
                <xsd:element ref="props"/>
                <xsd:any namespace="##other" processContents="strict"/>
            </xsd:choice>
        </xsd:sequence>
        <xsd:attribute name="name" type="xsd:string" use="required"/>
        <xsd:attribute name="ref" type="xsd:string"/>
        <xsd:attribute name="value" type="xsd:string"/>
    </xsd:complexType>

    <!-- base type for collections that have (possibly) typed nested values -->
    <xsd:complexType name="collectionType">
        <xsd:attribute name="value-type" type="xsd:string"/>
    </xsd:complexType>

    <!-- 'list' and 'set' collection type -->
    <xsd:complexType name="listOrSetType">
        <xsd:complexContent>
            <xsd:extension base="collectionType">
                <xsd:group ref="collectionElements"/>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>

    <!-- 'map' element type -->
    <xsd:complexType name="mapType">
        <xsd:complexContent>
            <xsd:extension base="collectionType">
                <xsd:sequence>
                    <xsd:element ref="description" minOccurs="0"/>
                    <xsd:choice minOccurs="0" maxOccurs="unbounded">
                        <xsd:element ref="entry"/>
                    </xsd:choice>
                </xsd:sequence>
                <xsd:attribute name="key-type" type="xsd:string"/>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>

    <!-- 'entry' element type -->
    <xsd:complexType name="entryType">
        <xsd:sequence>
            <xsd:element ref="key" minOccurs="0"/>
            <xsd:group ref="collectionElements"/>
        </xsd:sequence>
        <xsd:attribute name="key" type="xsd:string"/>
        <xsd:attribute name="key-ref" type="xsd:string"/>
        <xsd:attribute name="value" type="xsd:string"/>
        <xsd:attribute name="value-ref" type="xsd:string"/>
        <xsd:attribute name="value-type" type="xsd:string"/>
    </xsd:complexType>

    <!-- 'props' collection type -->
    <xsd:complexType name="propsType">
        <xsd:complexContent>
            <xsd:extension base="collectionType">
                <xsd:sequence>
                    <xsd:choice minOccurs="0" maxOccurs="unbounded">
                        <xsd:element ref="prop"/>
                    </xsd:choice>
                </xsd:sequence>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>

    <!-- 將true|false|default定義為枚舉布爾類型-->
    <xsd:simpleType name="defaultable-boolean">
        <xsd:restriction base="xsd:NMTOKEN">
            <xsd:enumeration value="default"/>
            <xsd:enumeration value="true"/>
            <xsd:enumeration value="false"/>
        </xsd:restriction>
    </xsd:simpleType>
</xsd:schema>

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM