This section presents several examples to illustrate the construction of application schema that employ the base GML schemas. All examples in this document have been validated using the XSV parser (version 1.166/1.77, 2000-09-28), a Python implementation that supports the current XML Schema Candidate Recommendation; several other parsers (both commercial and open -source implementations ) now also solidly support the current specification. An online validation service that uses XSV is available at this URL: <http://www.w3.org/2000/09/webdata/xsv>; while this checking service requires that all documents be web-accessible, it is also possible to download the source files and use the parser offline. Two examples are briefly summarized here and are explored in some depth using UML class diagrams, corresponding GML application schemas, and sample instance documents. One example is based on a simple model of the city of Cambridge, and is described more fully in Box 1.1 below.
In the 'Cambridge' example the first feature member uses only standard property names defined by GML, whereas the second feature member uses application-specific property names . Thus this example will demonstrate how GML is capable of being used in a custom application model, but it is not intended to provide examples of how the various types of geometry are encoded. A second example will be used to illustrate how GML can represent a hierarchy of feature collections; this will be referred to as the ' Schools ' example and it is summarized in Box 1.2.
Figure 6.1 is a UML diagram for the Cambridge example. As shown, allowable city members must be Road or River instances; a Mountain instance is not a valid member of the feature collection. Figure 6.1. UML diagram for the Cambridge example
Listing 6.1 is a custom city schema for the Cambridge example. The explicit reference to "city.xsd" in the root element of the instance document in Listing 6.2 (i.e. the value of the xsi:schemaLocation attribute) is not required, but in this case it provides a hint to the validating parser regarding the location of a relevant schema document. Listing 6.1 city.xsd View source<?xml version="1.0" encoding="UTF-8"?> <!-- File: city.xsd --> <schema targetNamespace="http://www.opengis.net/examples" xmlns:ex="http://www.opengis.net/examples" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gml="http://www.opengis.net/gml" xmlns="http://www.w3.org/2000/10/XMLSchema" elementFormDefault="qualified" version="2.03"> <annotation> <appinfo>city.xsd v2.03 2001-02</appinfo> <documentation xml:lang="en"> GML schema for the Cambridge example </documentation> </annotation> <!-- import constructs from the GML Feature and Geometry schemas --> <import namespace="http://www.opengis.net/gml" schemaLocation="feature.xsd"/> <!-- ============================================================== global element declarations =================================================================== --> <element name="CityModel" type="ex:CityModelType" substitutionGroup="gml:_FeatureCollection" /> <element name="cityMember" type="ex:CityMemberType" substitutionGroup="gml:featureMember"/> <element name="Road" type="ex:RoadType" substitutionGroup="ex:_CityFeature"/> <element name="River" type="ex:RiverType" substitutionGroup="ex:_CityFeature"/> <element name="Mountain" type="ex:MountainType" substitutionGroup="gml:_Feature"/> <!-- a label for restricting membership in the CityModel collection --> <element name="_CityFeature" type="gml:AbstractFeatureType" abstract="true" substitutionGroup="gml:_Feature"/> <!-- ============================================================== type definitions for city model =================================================================== --> <complexType name="CityModelType"> <complexContent> <extension base="gml:AbstractFeatureCollectionType"> <sequence> <element name="dateCreated" type="month"/> </sequence> </extension> </complexContent> </complexType> <complexType name="CityMemberType"> <annotation> <documentation> A cityMember is restricted to those features (or feature collections)that are declared equivalent to ex:_CityFeature. </documentation> </annotation> <complexContent> <restriction base="gml:FeatureAssociationType"> <sequence minOccurs="0"> <element ref="ex:_CityFeature"/> </sequence> <attributeGroup ref="gml:AssociationAttributeGroup"/> </restriction> </complexContent> </complexType> <complexType name="RiverType"> <complexContent> <extension base="gml:AbstractFeatureType"> <sequence> <element ref="gml:centerLineOf"/> </sequence> </extension> </complexContent> </complexType> <complexType name="RoadType"> <complexContent> <extension base="gml:AbstractFeatureType"> <sequence> <element name="linearGeometry" type="gml:LineStringPropertyType"/> <element name="classification" type="string"/> <element name="number" type="string"/> </sequence> </extension> </complexContent> </complexType> <!-- this is just here to demonstrate feature member restriction --> <complexType name="MountainType"> <complexContent> <extension base="gml:AbstractFeatureType"> <sequence> <element name="elevation" type="integer"/> </sequence> </extension> </complexContent> </complexType> </schema> Note that the application schema targets the 'ex' namespace; it imports the GML feature and geometry constructs from the 'gml' namespace. The <boundedBy> element is defined in the Feature schema; the <name> and <description> elements are also defined there. The <CityModel> element is an instance of the user -defined ex:CityModelType type that is derived by extension from gml:AbstractFeatureCollectionType . The types ex:RiverType and ex:RoadType are both derived by extension from gml:AbstractFeatureType , which is defined in the GML Feature schema; these derivations assure that the application schema conforms with the GML implementation specification of the OGC Simple Feature model. Listing 6.2 is a simple schema-valid instance document that conforms to city.xsd. A few words of explanation about the <Mountain> feature are in order! If this particular cityMember is uncommented in Listing 6.2, it will raise a validation error because even though the mountain is a well- formed GML feature, it is not recognized as a valid city feature. Note that in city.xsd the <Road> and <River> features are declared equivalent to ex:_CityFeature using the substitutionGroup attribute; this abstract element functions as a label that restricts membership in the <CityModel> feature collection ”only features so labeled are allowable members, as defined by CityMemberType . This technique demonstrates the application of the "Feature Filter" (see 5.2.7) that restricts membership in GML feature collections. One <cityMember> element in Listing 6.2 functions as a simple link by employing several XLink attributes; in effect we have a pointer entitled "Trinity Lane". Any <featureMember> element may behave as a simple link that references a remote resource. The link can point to a document fragment using an xpointer scheme that identifies a location, point, or range in the target document [ XPointer ]. In this case the value of the href attribute for the remote member contains an HTTP query string that can retrieve the feature instance; the remoteSchema attribute points to a schema fragment that constrains the instance: namely, the complex type definition in city.xsd that bears the name "RoadType". Listing 6.2 cambridge.xml View source<?xml version="1.0" encoding="UTF-8"?> <!-- File: cambridge.xml --> <CityModel xmlns="http://www.opengis.net/examples" xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/ examples city.xsd"> <gml:name>Cambridge</gml:name> <gml:boundedBy> <gml:Box srsName="http://www.opengis.net/gml/srs/epsg.xml#4326"> <gml:coord><gml:X>0.0</gml:X><gml:Y>0.0</gml:Y></gml:coord> <gml:coord><gml:X>100.0</gml:X><gml:Y>100.0</gml:Y></gml:coord> </gml:Box> </gml:boundedBy> <cityMember> <River> <gml:description>The river that runs through Cambridge. </gml:description> <gml:name>Cam</gml:name> <gml:centerLineOf> <gml:LineString srsName="http://www.opengis.net/gml/srs/ epsg.xml#4326"> <gml:coord><gml:X>0</gml:X><gml:Y>50</gml:Y></gml:coord> <gml:coord><gml:X>70</gml:X><gml:Y>60</gml:Y></gml:coord> <gml:coord><gml:X>100</gml:X><gml:Y>50</gml:Y></gml:coord> </gml:LineString> </gml:centerLineOf> </River> </cityMember> <cityMember> <Road> <gml:name>M11</gml:name> <linearGeometry> <gml:LineString srsName="http://www.opengis.net/gml/srs/ epsg.xml#4326"> <gml:coord><gml:X>0</gml:X><gml:Y>5.0</gml:Y></gml:coord> <gml:coord><gml:X>20.6</gml:X><gml:Y>10.7</gml:Y> </gml:coord> <gml:coord><gml:X>80.5</gml:X><gml:Y>60.9</gml:Y> </gml:coord> </gml:LineString> </linearGeometry> <classification>motorway</classification> <number>11</number> </Road> </cityMember> <cityMember xlink:type="simple" xlink:title="Trinity Lane" xlink:href="http://www.foo.net/cgi-bin/wfs?FeatureID=C10239" gml:remoteSchema="city.xsd#xpointer (//complexType[@name='RoadType'])"/> <!-- a mountain doesn't belong here! Uncomment this cityMember and see the parser complain! <cityMember> <Mountain> <gml:description>World's highest mountain is in Nepal! </gml:description> <gml:name>Everest</gml:name> <elevation>8850</elevation> </Mountain> </cityMember> --> <dateCreated>2000-11</dateCreated> </CityModel> Figure 6.2 is a UML diagram for the Schools example. The SchoolDistrictclass is associated with the State class via the featureMember relationship, and instances of the School or College classes are members of the SchoolDistrict collection. Figure 6.2. UML diagram for the Schools example
Listing 6.3 is an application schema for the Schools example. The purpose of this example is to demonstrate that feature collections may indeed contain other feature collections. To keep things fairly simple no attempt has been made to restrict membership in any of the collections; this means that a valid instance document could contain any GML feature within the <State> and <SchoolDistrict> collections, not just those pertaining to educational institutions. Sub-section 5.2.7 describes a design pattern for restricting collection membership. Listing 6.3 schools.xsd View source<?xml version="1.0" encoding="UTF-8"?> <!-- File: schools.xsd --> <schema targetNamespace="http://www.opengis.net/examples" xmlns:ex="http://www.opengis.net/examples" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gml="http://www.opengis.net/gml" xmlns="http://www.w3.org/2000/10/XMLSchema" elementFormDefault="qualified" version="2.01"> <annotation> <appinfo>schools.xsd v2.01 2001-02</appinfo> <documentation xml:lang="en"> GML schema for Schools example. </documentation> </annotation> <!-- import constructs from the GML Feature and Geometry schemas --> <import namespace="http://www.opengis.net/gml" schemaLocation="feature.xsd"/> <!-- ============================================================== global element declarations =============================================================== --> <element name="State" type="ex:StateType" substitutionGroup="gml:_FeatureCollection"/> <element name="SchoolDistrict" type="ex:SchoolDistrictType" substitutionGroup="gml:_FeatureCollection"/> <element name="schoolMember" type="gml:FeatureAssociationType" substitutionGroup="gml:featureMember"/> <element name="School" type="ex:SchoolType" substitutionGroup="gml:_Feature"/> <element name="College" type="ex:CollegeType" substitutionGroup="gml:_Feature"/> <element name="address" type="string"/> <!-- ============================================================== type definitions for state educational institutions =============================================================== --> <complexType name="StateType"> <complexContent> <extension base="gml:AbstractFeatureCollectionType"> <sequence> <element name="studentPopulation" type="integer"/> </sequence> </extension> </complexContent> </complexType> <complexType name="SchoolDistrictType"> <complexContent> <extension base="gml:AbstractFeatureCollectionType"> <sequence> <element ref="gml:extentOf"/> </sequence> </extension> </complexContent> </complexType> <complexType name="SchoolType"> <complexContent> <extension base="gml:AbstractFeatureType"> <sequence> <element ref="ex:address"/> <element ref="gml:location"/> </sequence> </extension> </complexContent> </complexType> <complexType name="CollegeType"> <complexContent> <extension base="gml:AbstractFeatureType"> <sequence> <element ref="ex:address"/> <element ref="gml:pointProperty" /> </sequence> </extension> </complexContent> </complexType> </schema> A few interesting things are happening in this example. The root <State> element is an instance of ex:StateType , which is derived from the abstract gml:AbstractFeatureCollectionType defined in the GML Feature schema. One of the child elements, <SchoolDistrict>, is also a feature collection; in effect we have a feature collection containing a feature collection as one of its members. Listing 6.4 is a conforming instance document. Refer to Box 1.2 for a summary of the example. Listing 6.4 schools.xml View source<?xml version="1.0" encoding="UTF-8"?> <!-- File: schools.xml --> <State xmlns="http://www.opengis.net/examples" xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/ examples schools.xsd"> <gml:description> Educational institutions with student populations exceeding 500. </gml:description> <gml:name>School districts in the North Region.</gml:name> <gml:boundedBy> <gml:Box srsName="http://www.opengis.net/gml/srs/epsg.xml#4326"> <gml:coord><gml:X>0</gml:X><gml:Y>0</gml:Y></gml:coord> <gml:coord><gml:X>50</gml:X><gml:Y>50</gml:Y></gml:coord> </gml:Box> </gml:boundedBy> <gml:featureMember> <SchoolDistrict> <gml:name>District 28</gml:name> <gml:boundedBy> <gml:Box srsName="http://www.opengis.net/gml/srs/ epsg.xml#4326"> <gml:coord><gml:X>0</gml:X><gml:Y>0</gml:Y></gml:coord> <gml:coord><gml:X>50</gml:X><gml:Y>40</gml:Y></gml:coord> </gml:Box> </gml:boundedBy> <schoolMember> <School> <gml:name>Alpha</gml:name> <address>100 Cypress Ave.</address> <gml:location> <gml:Point srsName="http://www.opengis.net/gml/srs/ epsg.xml#4326"> <gml:coord><gml:X>20.0</gml:X><gml:Y>5.0</gml:Y> </gml:coord> </gml:Point> </gml:location> </School> </schoolMember> <schoolMember> <School> <gml:name>Beta</gml:name> <address>1673 Balsam St.</address> <gml:location> <gml:Point srsName="http://www.opengis.net/gml/srs/ epsg.xml#4326"> <gml:coord><gml:X>40.0</gml:X><gml:Y>5.0</gml:Y> </gml:coord> </gml:Point> </gml:location> </School> </schoolMember> <gml:extentOf> <gml:Polygon srsName="http://www.opengis.net/gml/srs/ epsg.xml#4326"> <gml:outerBoundaryIs> <gml:LinearRing> <gml:coord><gml:X>0</gml:X><gml:Y>0</gml:Y></gml:coord> <gml:coord><gml:X>50</gml:X><gml:Y>0</gml:Y></gml:coord> <gml:coord><gml:X>50</gml:X><gml:Y>40</gml:Y></gml:coord> <gml:coord><gml:X>0</gml:X><gml:Y>0</gml:Y></gml:coord> </gml:LinearRing> </gml:outerBoundaryIs> </gml:Polygon> </gml:extentOf> </SchoolDistrict> </gml:featureMember> <gml:featureMember> <SchoolDistrict> <gml:name>District 32</gml:name> <gml:boundedBy> <gml:Box srsName="http://www.opengis.net/gml/srs/ epsg.xml#4326"> <gml:coord><gml:X>0</gml:X><gml:Y>0</gml:Y></gml:coord> <gml:coord><gml:X>30</gml:X><gml:Y>50</gml:Y></gml:coord> </gml:Box> </gml:boundedBy> <schoolMember> <School> <gml:name>Gamma</gml:name> <address>651 Sequoia Ave.</address> <gml:location> <gml:Point srsName="http://www.opengis.net/gml/srs/ epsg.xml#4326"> <gml:coord><gml:X>5.0</gml:X><gml:Y>20.0</gml:Y> </gml:coord> </gml:Point> </gml:location> </School> </schoolMember> <schoolMember xlink:type="simple" xlink:href="http:abc.com"> <College> <gml:name>Delta</gml:name> <address>260 University Blvd.</address> <gml:pointProperty> <gml:Point srsName="http://www.opengis.net/gml/srs/ epsg.xml#4326"> <gml:coord><gml:X>5.0</gml:X><gml:Y>40.0</gml:Y> </gml:coord> </gml:Point> </gml:pointProperty> </College> </schoolMember> <schoolMember xlink:type="simple" xlink:title= "Epsilon High School" xlink:href="http:www.state.gov/schools/cgi-bin/ wfs?schoolID=hs736" gml:remoteSchema="schools.xsd#xpointer (//complexType[@name='SchoolType'])"/> <gml:extentOf> <gml:Polygon srsName="http://www.opengis.net/gml/srs/ epsg.xml#4326"> <gml:outerBoundaryIs> <gml:LinearRing> <gml:coord><gml:X>0</gml:X><gml:Y>0</gml:Y></gml:coord> <gml:coord><gml:X>40</gml:X><gml:Y>50</gml:Y></gml:coord> <gml:coord><gml:X>50</gml:X><gml:Y>50</gml:Y></gml:coord> <gml:coord><gml:X>0</gml:X><gml:Y>0</gml:Y></gml:coord> </gml:LinearRing> </gml:outerBoundaryIs> </gml:Polygon> </gml:extentOf> </SchoolDistrict> </gml:featureMember> <studentPopulation>392620</studentPopulation> </State> Note the use of <coord> elements to convey coordinate values; the XML parser constrains the number of tuples according to geometry type. For example, a <Point> element has exactly one coordinate tuple, and a <LinearRing> has at least four. The final example illustrates the construction of a "horizontal" application schema in that it might be applied to a range of application domains. This example is simple data interchange schema that facilitates the exchange of application-level data structures (i.e. features and/or feature collections); such a schema provides a generic means of transferring instances of simple features. Listing 6.5 is a sample instance document that conforms to the schema in Listing 6.6. A feature may include any of the predefined simple geometric properties (e.g. those that return Points, Polygons, or LineStrings). Non-spatial properties must reflect one of the atomic datatypes of XML Schema. Listing 6.5 gmlpacket.xml View source<?xml version="1.0" encoding="UTF-8"?> <!-- File: gmlpacket.xml --> <gmlPacket xmlns="http://www.opengis.net/examples/packet" xmlns:gml="http://www.opengis.net/gml" xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance" xsi:schemaLocation= "http://www.opengis.net/examples/packet gmlpacket.xsd"> <gml:description>Road network elements</gml:description> <gml:boundedBy> <gml:null>unknown</gml:null> </gml:boundedBy> <packetMember> <StaticFeature fid="Highway-99" featureType="Road"> <gml:centerLineOf> <gml:LineString> <gml:coordinates>...</gml:coordinates> </gml:LineString> </gml:centerLineOf> <property> <propertyName>numLanes</propertyName> <value dataType="integer">2</value> </property> <property> <propertyName>surfaceType</propertyName> <value dataType="string">asphalt</value> </property> </StaticFeature> </packetMember> <Metadata> <title>Vancouver-Squamish corridor</title> </Metadata> </gmlPacket> Listing 6.6 is the 'gmlpacket' schema. The <gmlPacket> element is the root feature collection; this schema restricts allowable feature members to instances of pak:StaticFeatureType . None of the type definitions in the gmlpacket schema can be extended or restricted in any manner, and this schema cannot serve as the basis for any other application schema (i.e. it cannot be imported or included into another schema). Listing 6.6 gmlpacket.xsd View source<?xml version="1.0" encoding="UTF-8"?> <!-- File: gmlpacket.xsd --> <schema targetNamespace="http://www.opengis.net/examples/packet" xmlns:pak="http://www.opengis.net/examples/packet" xmlns:gml="http://www.opengis.net/gml" xmlns="http://www.w3.org/2000/10/XMLSchema" elementFormDefault="qualified" finalDefault="#all" version="0.5"> <annotation> <appinfo>gmlpacket.xsd v0.5 2001-02</appinfo> <documentation xml:lang="en"> GML schema for simple data transfer. </documentation> </annotation> <!-- import constructs from the GML Feature and Geometry schemas --> <import namespace="http://www.opengis.net/gml" schemaLocation="feature.xsd"/> <element name="gmlPacket" type="pak:GMLPacketType"/> <element name="packetMember" type="pak:packetMemberType"/> <element name="StaticFeature" type="pak:StaticFeatureType"/> <complexType name="GMLPacketBaseType"> <complexContent> <restriction base="gml:AbstractFeatureCollectionType"> <sequence> <element ref="gml:description" minOccurs="0"/> <element ref="gml:name" minOccurs="0"/> <element ref="gml:boundedBy"/> <element ref="pak:packetMember" minOccurs="0" maxOccurs="unbounded"/> </sequence> <attribute name="fid" type="ID" use="optional"/> </restriction> </complexContent> </complexType> <complexType name="GMLPacketType"> <complexContent> <extension base="pak:GMLPacketBaseType"> <sequence> <element name="Metadata" type="pak:MetadataType" minOccurs="0"/> </sequence> </extension> </complexContent> </complexType> <complexType name="packetMemberType"> <complexContent> <restriction base="gml:FeatureAssociationType"> <sequence minOccurs="0"> <element ref="pak:StaticFeature"/> </sequence> <attributeGroup ref="gml:AssociationAttributeGroup"/> </restriction> </complexContent> </complexType> <complexType name="MetadataType"> <sequence> <element name="origin" type="string" minOccurs="0"/> <element name="title" type="string" minOccurs="0"/> <element name="abstract" type="string" minOccurs="0"/> </sequence> </complexType> <complexType name="StaticFeatureType"> <complexContent> <extension base="gml:AbstractFeatureType"> <sequence> <element ref="gml:pointProperty" minOccurs="0"/> <element ref="gml:polygonProperty" minOccurs="0"/> <element ref="gml:lineStringProperty" minOccurs="0"/> <element name="property" type="pak:PropertyType" minOccurs="0" maxOccurs="unbounded"/> </sequence> <attribute name="featureType" type="string" use="required"/> </extension> </complexContent> </complexType> <complexType name="PropertyType"> <sequence> <element name="propertyName" type="string"/> <element name="value"> <complexType> <simpleContent> <extension base="string"> <attribute name="dataType" type="pak:DataType" use="required"/> </extension> </simpleContent> </complexType> </element> </sequence> </complexType> <simpleType name="DataType"> <restriction base="string"> <enumeration value="string"/> <enumeration value="integer"/> <enumeration value="long"/> <enumeration value="decimal"/> <enumeration value="boolean"/> <enumeration value="time"/> <enumeration value="date"/> </restriction> </simpleType> </schema> |