<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">

  <!-- Attribute Definitions -->
  <xs:attribute name="Count" type="xs:nonNegativeInteger" />
  <xs:attribute name="Name" type="xs:string" />
  <xs:attribute name="Code" type="xs:string" />
  <xs:attribute name="Description" type="xs:string" />
  <xs:attribute name="Date" type="xs:dateTime" />
  <xs:attribute name="Created" type="xs:dateTime" />
  <xs:attribute name="DataType" type="xs:string" />
  <xs:attribute name="Value" type="xs:string" />
  <xs:attribute name="ID" type="xs:string" />
  <xs:attribute name="SRS" type="xs:string" />
  <xs:attribute name="Domain" type="xs:string" />

  <!-- Attribute Group Definitions -->
  <xs:attributeGroup name="CodeAndName">
    <xs:attribute ref="Code" use="required" />
    <xs:attribute ref="Name" use="required" />
  </xs:attributeGroup>
  <xs:attributeGroup name="NameAndDataType">
    <xs:attribute ref="Name" use="required" />
    <xs:attribute ref="DataType" use="required" />
  </xs:attributeGroup>
  <xs:attributeGroup name="NameAndValue">
    <xs:attribute ref="Name" use="required" />
    <xs:attribute ref="Value" use="required" />
  </xs:attributeGroup>
  <xs:attributeGroup name="IdName">
    <xs:attribute ref="ID" use="required"/>
    <xs:attribute ref="Name" use="required" />
  </xs:attributeGroup>
  <xs:attributeGroup name="CountIdName">
    <xs:attribute ref="Count" use="required" />
    <xs:attributeGroup ref="IdName" />
  </xs:attributeGroup>
  
  <xs:element name="Dataset">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Header" />
        <xs:element ref="Request" minOccurs="0" />
        <xs:element ref="Report" minOccurs="0" />
      </xs:sequence>
      <xs:attribute name="DatasetID" use="required" type="xs:string" />
      <xs:attribute name="Schema" use="required" type="xs:anyURI" />
    </xs:complexType>
  </xs:element>
  
  <xs:element name="Header">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="DatasetType" />
        <xs:element ref="MeasurementSystem" />
        <xs:element ref="Language" />
        <xs:element ref="TimeZone" />
        <xs:element ref="Comment" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  
  <xs:element name="DatasetType">
    <xs:complexType>
      <xs:attributeGroup ref="CodeAndName" />
    </xs:complexType>
  </xs:element>
  
  <xs:element name="MeasurementSystem">
    <xs:complexType>
      <xs:attributeGroup ref="CodeAndName" />
    </xs:complexType>
  </xs:element>
  
  <xs:element name="Language">
    <xs:complexType>
      <xs:attributeGroup ref="CodeAndName" />
    </xs:complexType>
  </xs:element>

  <xs:element name="TimeZone">
    <xs:complexType>
      <xs:attributeGroup ref="CodeAndName" />
    </xs:complexType>
  </xs:element>
  
  <xs:element name="Comment" type="xs:string" />
  
  <xs:element name="Parameter">
    <xs:complexType>
      <xs:attributeGroup ref="NameAndDataType" />
    </xs:complexType>
  </xs:element>
  
  <xs:element name="ValueElement">
    <xs:complexType>
      <xs:attributeGroup ref="NameAndValue" />
    </xs:complexType>
  </xs:element>
  
  <xs:element name="Request">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="FormatSpecification" />
        <xs:element ref="ParameterSpecification" />
      </xs:sequence>
      <xs:attribute ref="Date" use="required" />
      <xs:attribute ref="Name" use="required" />
    </xs:complexType>
  </xs:element>
  
  <xs:element name="FormatSpecification">
    <xs:complexType>
      <xs:sequence>
        <xs:element maxOccurs="unbounded" ref="FormatArrayDefinition" />
        <xs:element ref="FormatArray" />
      </xs:sequence>
      <xs:attribute ref="Count" use="required" />
      <xs:attribute ref="Name" use="required" />
      <xs:attribute name="Schema" use="required" type="xs:string" />
    </xs:complexType>
  </xs:element>
  
  <xs:element name="FormatArrayDefinition">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Parameter" maxOccurs="unbounded" />
        <xs:element ref="Comment" minOccurs="0" maxOccurs="1" />
      </xs:sequence>
      <xs:attribute ref="Name" use="required" />
    </xs:complexType>
  </xs:element>
  
  <xs:element name="FormatArray">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="FormatElement" minOccurs="0" maxOccurs="unbounded" />
      </xs:sequence>
      <xs:attribute ref="Count" use="required" />
    </xs:complexType>
  </xs:element>
  
  <xs:element name="FormatElement">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="ValueElement" maxOccurs="unbounded" />
      </xs:sequence>
      <xs:attribute ref="Count" use="required" />
    </xs:complexType>
  </xs:element>
  
  <xs:element name="ParameterSpecification">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="ParameterArrayDefinition" />
        <xs:element ref="ParameterArray" />
      </xs:sequence>
      <xs:attribute ref="Count" use="required" />
    </xs:complexType>
  </xs:element>
  
  <xs:element name="ParameterArrayDefinition">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Item" />
        <xs:element ref="Comment" minOccurs="0" maxOccurs="1"/>
      </xs:sequence>
      <xs:attributeGroup ref="IdName" />
    </xs:complexType>
  </xs:element>
  
  <xs:element name="ParameterArray">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Parameter" minOccurs="0" maxOccurs="unbounded" />
      </xs:sequence>
      <xs:attribute ref="Count" use="required" />
    </xs:complexType>
  </xs:element>
  
  <xs:element name="ParameterElement">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="ValueElement" minOccurs="0" maxOccurs="unbounded" />
      </xs:sequence>
      <xs:attribute ref="Count" use="required" />
    </xs:complexType>
  </xs:element>
  
  <xs:element name="Report">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="CoverageSet" />
      </xs:sequence>
      <xs:attributeGroup ref="CountIdName" />
    </xs:complexType>
  </xs:element>
  
  <xs:element name="CoverageSet">
    <xs:complexType>
      <xs:sequence minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="Coverage" />
      </xs:sequence>
      <xs:attribute ref="Count" use="required" />
    </xs:complexType>
  </xs:element>
  
  <xs:element name="Coverage">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="LocationSet" />
        <xs:element ref="ParameterSet" minOccurs="0" maxOccurs="unbounded" />
      </xs:sequence>
      <xs:attributeGroup ref="CountIdName" />
    </xs:complexType>
  </xs:element>
  
  <xs:element name="LocationSet">
    <xs:complexType>
      <xs:sequence minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="LocationDataElement" />
      </xs:sequence>
      <xs:attribute ref="Count" />
    </xs:complexType>
  </xs:element>

  <xs:element name="LocationDataElement">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Coordinates" minOccurs="0" />
        <xs:element ref="OtherIdentifier" minOccurs="0" />
        <xs:element ref="LocationDataArray" minOccurs="0" />
      </xs:sequence>
      <xs:attribute ref="ID" />
    </xs:complexType>
  </xs:element>

  <xs:element name="Coordinates">
    <xs:complexType>
      <xs:choice>
        <xs:element ref="Point" />
        <xs:element name="Line" type="LineType" />
        <xs:element name="BoundingBox" type="BoundingBoxType" />
        <xs:element name="Polyline" type="PolylineType" />
        <xs:element name="Polygon" type="PolygonType" />
      </xs:choice>
      <xs:attribute ref="coordinateUnits" use="optional" default="Decimal Degrees" />
      <xs:attribute ref="SRS" use="optional" default="WGS84" />
    </xs:complexType>
  </xs:element>

  <xs:attribute name="coordinateUnits">
    <xs:simpleType>
      <xs:restriction base="xs:string">
        <xs:pattern value="Decimal Degrees|Degree Minute Second|Feet|Meters|Miles|Kilometers" />
      </xs:restriction>
    </xs:simpleType>
  </xs:attribute>
  
  <xs:element name="Point" type="PointType" />
  
  <xs:complexType name="LineType">
    <xs:sequence>
      <xs:element ref="Point" minOccurs="2" maxOccurs="2" />
    </xs:sequence>
  </xs:complexType>
  
  <xs:complexType name="PolylineType">
    <xs:sequence>
      <xs:element ref="Point" minOccurs="3" maxOccurs="unbounded" />
    </xs:sequence>
  </xs:complexType>
  
  <xs:complexType name="PolygonType">
    <xs:sequence>
      <xs:element ref="Point" minOccurs="3" maxOccurs="unbounded" />
    </xs:sequence>
  </xs:complexType>
  
  <xs:complexType name="BoundingBoxType">
    <xs:sequence>
      <!-- This section is for the opposite corner definitions of a box -->
      <xs:element name="CornerOne" type="PointType" maxOccurs="1" minOccurs="1" />
      <xs:element name="OpposingCorner" type="PointType" maxOccurs="1" minOccurs="1" />
    </xs:sequence>
  </xs:complexType>
  
  <xs:group name="CoordGroup">
    <xs:choice>
      <xs:sequence>
        <xs:element name="Latitude" type="xs:float" maxOccurs="1" minOccurs="1" />
        <xs:element name="Longitude" type="xs:float" maxOccurs="1" minOccurs="1" />
      </xs:sequence>
      <xs:sequence>
        <xs:element name="Northing" type="xs:float" maxOccurs="1" minOccurs="1" />
        <xs:element name="Easting" type="xs:float" maxOccurs="1" minOccurs="1" />
      </xs:sequence>
      <xs:sequence>
        <xs:element name="LocalX" type="xs:float" maxOccurs="1" minOccurs="1" />
        <xs:element name="LocalY" type="xs:float" maxOccurs="1" minOccurs="1" />
      </xs:sequence>
    </xs:choice>
  </xs:group>
  
  <xs:complexType name="PointType">
    <xs:group ref="CoordGroup" />
    <xs:attribute name="order" type="xs:nonNegativeInteger" />
  </xs:complexType>

  <xs:element name="OtherIdentifier">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="StationID" type="ServiceInvocation" minOccurs="0" maxOccurs="1" />
        <xs:element ref="Station" minOccurs="0" maxOccurs="1"/>
        <xs:element name="State" type="xs:string" minOccurs="0" maxOccurs="1" />
        <xs:element name="County" type="xs:string" minOccurs="0" maxOccurs="1" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name="Station">
    <xs:complexType>
      <xs:attribute ref="ID" use="required" />
      <xs:attribute ref="Domain" use="required" />
    </xs:complexType>
  </xs:element>

  <xs:complexType name="ServiceInvocation">
    <xs:sequence>
      <xs:element ref="ParameterElement" minOccurs="0" maxOccurs="1"/>
    </xs:sequence>
    <xs:attribute ref="Domain" use="required" />
    <!-- example: URL for a de-referencing web service -->
    <xs:attribute name="GazetteerURL" type="xs:anyURI" use="optional" />
  </xs:complexType>

  <xs:element name="LocationDataArray">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="DataElement" minOccurs="0" maxOccurs="unbounded" />
      </xs:sequence>
      <xs:attribute ref="Count" use="required" />
    </xs:complexType>
  </xs:element>
    
  <xs:element name="ParameterSet">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="DataElementSet" />
      </xs:sequence>
      <xs:attribute ref="Created" use="optional" />
      <xs:attribute ref="Code" use="required" />
      <xs:attributeGroup ref="IdName" />
    </xs:complexType>
  </xs:element>

  <xs:element name="DataElementSet">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="DataElement" minOccurs="0" maxOccurs="unbounded" />
      </xs:sequence>
      <xs:attribute ref="Count" use="required" />
    </xs:complexType>
  </xs:element>

  <xs:element name="Item">
    <xs:complexType>
      <xs:attribute ref="DataType" />
      <xs:attribute name="Description" type="xs:string" />
      <xs:attribute name="Location" type="xs:string" />
      <xs:attribute ref="Name" use="required" />
      <xs:attribute name="Units" type="xs:string" />
      <xs:attribute ref="Value"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="DataElement">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Comment" minOccurs="0" maxOccurs="1" />
        <xs:sequence minOccurs="0">
          <xs:element ref="DataElementArrayDefinition" />
          <xs:element ref="DataElementArray" />
        </xs:sequence>
        <xs:element minOccurs="0" maxOccurs="unbounded" ref="Item" />
      </xs:sequence>
      <xs:attribute name="CreateDateTime" type="xs:dateTime" />
      <xs:attribute name="EndingDateTime" type="xs:dateTime" />
      <xs:attribute name="ModifyDateTime" type="xs:dateTime" />
      <xs:attribute name="StartingDateTime" type="xs:dateTime" />
      <xs:attributeGroup ref="CountIdName" />
    </xs:complexType>
  </xs:element>

  <xs:element name="DataElementArrayDefinition">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Item" minOccurs="0" maxOccurs="unbounded" />
      </xs:sequence>
      <xs:attributeGroup ref="IdName" />
    </xs:complexType>
  </xs:element>

  <xs:element name="DataElementArray">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="DataElement" minOccurs="0" maxOccurs="unbounded" />
      </xs:sequence>
      <xs:attribute ref="Count" use="required" />
    </xs:complexType>
  </xs:element>

</xs:schema>
