Scratch Pad: Difference between revisions

From OPeNDAP Documentation
⧼opendap2-jumptonavigation⧽
No edit summary
 
(9 intermediate revisions by the same user not shown)
Line 1: Line 1:
On this page we look at transforming the OtherXML dap:Attribute type to RDF.
The DAP Relational Database Server II (DRDS-II) is a (as yet to funded) project that will provide a DAP service layer for relational databases systems. Previously this was (partially) accomplished by a Java servlet known as the DODS Relational Database Server (DRDS).


==SourceXML==
== Overview ==


    <Attribute name="xmlTest" type="OtherXML" relationship="is-a">
=== Automated catalog generation vs. external configuration ===
        <t:level0 xmlns:t="http://namespace.t" t:foo1="namespacedattribute" foo2="nonamespaceAttribute">
            <t:level1>simpleContent</t:level1>
            <t:level1>
                <t:level2>
                    <t:level3>simpleContent</t:level3>
                </t:level2>
            </t:level1>
            TextContent of Complex Type
        </t:level0>
    </Attribute>


==RDF==
Should the DRDS-II interrogate the database to learn the table and key structures so that it can automatically build a ''catalog'' of DAP data objects that represent the database holdings? Or, should the DRDS-II rely (as it's predecessor did) on having the operator develop a DDS/DDX (or some other configuration item) for each data holding?


<?xml version="1.0" encoding="UTF-8"?>
=== Data model representation: Tables/Queries as Sequences ===
<rdf:RDF xmlns:dap="http://xml.opendap.org/ns/DAP/3.3#"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:cf="http://iridl.ldeo.columbia.edu/ontologies/cf-att.owl#"
        xmlns:dapObj="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#"
        xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
        xmlns:owl="http://www.w3.org/2002/07/owl#"
        xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
        xml:base="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx">
  <owl:Ontology rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf">
      <owl:imports rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl"/>
      <owl:imports rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/NetcdfConventionRegistry.owl"/>
  </owl:Ontology>
  <dapObj:Dataset rdf:about="">
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
      <dapObj:dataset_id rdf:datatype="http://www.w3.org/2001/XMLSchema#string"/>
      <dapObj:type>
        <t:level0 xmlns:t="http://namespace.t" xmlns:grddl="http://www.w3.org/2003/g/data-view#"
                  xmlns="http://xml.opendap.org/ns/DAP/3.3#"
                  t:foo1="namespacedattribute">
            <dapObj:xmlAttribute dapObj:name="foo2" rdf:value="nonamespaceAttribute"/>
            <dapObj:xmlText>
            TextContent of Complex Type
        </dapObj:xmlText>
            <t:level1>simpleContent</t:level1>
            <dapObj:xmlContains>
              <t:level1>
                  <dapObj:xmlContains>
                    <t:level2>
                        <t:level3>simpleContent</t:level3>
                    </t:level2>
                  </dapObj:xmlContains>
              </t:level1>
            </dapObj:xmlContains>
        </t:level0>
      </dapObj:type>
  </dapObj:Dataset>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#xmlTest">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
</rdf:RDF>


== Hacked HFRadar Example ==


=== Example 1 ===
In the world of the RDBMS everything is structurally a ''row set'': A collection (tuple) of columns (variables) whose length my not be known until the content is delivered in total.  Tables are ''row sets''.  A database ''view'' is a ''row set''. SQL queries return ''row sets''. SQL JOIN operations take ''row sets' as input and produce ''row sets''.


In which an entire coverage description is inserted into a DDX as OtherXML
''Row sets'' map naturally to the DAP Sequence data type, thus a reasonable representation of an SQL query is a Sequence: A repeating tuple of unknown length.


==== Source XML ====
When a database contains multiple tables or views, each one could be represented as a DAP Sequence. Thus a DDS might contain multiple Sequences each representing a single table  or view in the RDBMS:
<pre>
<?xml version="1.0" encoding="UTF-8"?>
<Dataset name="200803061600_HFRadar_USEGC_6km_rtv_SIO.nc"
        xmlns:grddl="http://www.w3.org/2003/g/data-view#"
        grddl:transformation="http://xml.opendap.org/transforms/ddxToRdfTriples.xsl"
        xmlns="http://xml.opendap.org/ns/DAP/3.3#"
        xmlns:dap="http://xml.opendap.org/ns/DAP/3.3#"
        dap_version="3.2"
        xmlns:xml="http://www.w3.org/XML/1998/namespace"
        xml:base="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx" >


    <Attribute name="wcsStuff" type="OtherXML" relationship="is-a" >
  Dataset {
            <CoverageDescription xmlns="http://www.opengis.net/wcs/1.1" xmlns:ows="http://www.opengis.net/ows/1.1"
    Sequence {
                                xmlns:owcs="http://www.opengis.net/wcs/1.1/ows" xmlns:gml="http://www.opengis.net/gml/3.2"
        String FirstName;
                                xmlns:xlink="http://www.w3.org/1999/xlink"
        String LastName;
                                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        String PhoneNumber;
                                xmlns:schemaLocation="http://www.opengis.net/wcs/1.1 http://schemas.opengis.net/wcs/1.1.0/wcsDescribeCoverage.xsd  http://www.opengis.net/ows/1.1  http://schemas.opengis.net/ows/1.1.0/owsAll.xsd  http://www.opengis.net/wcs/1.1/ows http://schemas.opengis.net/wcs/1.1.0/owsDataIdentification.xsd http://www.opengis.net/gml/3.2  http://schemas.opengis.net/gml/3.2.1/gml.xsd">
    } Authors;
                <ows:Title>Near-Real Time Surface Ocean Velocity</ows:Title>
                <ows:Abstract>CoverageDescription generated by OPeNDAP WCS UseCase 2.0</ows:Abstract>
    Sequence {
                <Identifier>coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc</Identifier>
        String Title;
                <Domain>
        String Publisher;
                    <SpatialDomain>
        Int16  Pages;
                        <ows:BoundingBox crs="urn:ogc:def:crs:EPSG::4326">
        String  CopyrightDate;
                            <ows:LowerCorner>-97.8839 21.736</ows:LowerCorner>
        String  ISBN;
                            <ows:UpperCorner>-57.2312 46.4944</ows:UpperCorner>
    } Books;
                        </ows:BoundingBox>
                    </SpatialDomain>
} Inventory;
                    <TemporalDomain>
                        <gml:timePosition>2008-03-27T16:00:00.000Z</gml:timePosition>
                    </TemporalDomain>
                </Domain>
                <Range>
                    <Field>
                        <ows:Title>surface_eastward_sea_water_velocity</ows:Title>
                        <ows:Abstract>Eastward component of a 2D sea surface velocity vector.</ows:Abstract>
                        <Identifier>u</Identifier>
                        <Definition>
                            <ows:AnyValue/>
                        </Definition>
                        <NullValue>-32768</NullValue>
                        <owcs:InterpolationMethods>
                            <owcs:DefaultMethod>nearest</owcs:DefaultMethod>
                        </owcs:InterpolationMethods>
                    </Field>
                    <Field>
                        <ows:Title>surface_northward_sea_water_velocity</ows:Title>
                        <ows:Abstract>Northward component of a 2D sea surface velocity vector.</ows:Abstract>
                        <Identifier>v</Identifier>
                        <Definition>
                            <ows:AnyValue/>
                        </Definition>
                        <NullValue>-32768</NullValue>
                        <owcs:InterpolationMethods>
                            <owcs:DefaultMethod>nearest</owcs:DefaultMethod>
                        </owcs:InterpolationMethods>
                    </Field>
                    <Field>
                        <ows:Title>longitudinal dilution of precision</ows:Title>
                        <ows:Abstract>The longitudinal dilution of precision (DOPx) represents the\\012contribution of the
                            radars&apos; configuration geometry to\\012uncertainty in the eastward velocity estimate (u). DOPx
                            is a\\012direct multiplier of the standard error in obtaining the\\012standard deviation for the
                            eastward velocity estimate from the\\012least squares best fit. DOPx and DOPy are commonly used
                            to\\012obtain the geometric dilution of precision\\012(GDOP = sqrt(DOPx^2 + DOPy^2)), a useful
                            metric for filtering\\012errant velocities due to poor geometry.
                        </ows:Abstract>
                        <Identifier>DOPx</Identifier>
                        <Definition>
                            <ows:AnyValue/>
                        </Definition>
                        <NullValue>-32768</NullValue>
                        <owcs:InterpolationMethods>
                            <owcs:DefaultMethod>nearest</owcs:DefaultMethod>
                        </owcs:InterpolationMethods>
                    </Field>
                    <Field>
                        <ows:Title>latitudinal dilution of precision</ows:Title>
                        <ows:Abstract>The latitudinal dilution of precision (DOPy) represents the\\012contribution of the radars&apos;
                            configuration geometry to\\012uncertainty in the northward velocity estimate (v). DOPy is
                            a\\012direct multiplier of the standard error in obtaining the\\012standard deviation for the
                            northward velocity estimate from the\\012least squares best fit. DOPx and DOPy are commonly used
                            to\\012obtain the geometric dilution of precision\\012(GDOP = sqrt(DOPx^2 + DOPy^2)), a useful
                            metric for filtering\\012errant velocities due to poor geometry.
                        </ows:Abstract>
                        <Identifier>DOPy</Identifier>
                        <Definition>
                            <ows:AnyValue/>
                        </Definition>
                        <NullValue>-32768</NullValue>
                        <owcs:InterpolationMethods>
                            <owcs:DefaultMethod>nearest</owcs:DefaultMethod>
                        </owcs:InterpolationMethods>
                    </Field>
                </Range>
                <SupportedCRS>urn:ogc:def:crs:EPSG::4326</SupportedCRS>
                <SupportedFormat>netcdf-cf1.0</SupportedFormat>
                <SupportedFormat>dap2.0</SupportedFormat>
            </CoverageDescription>
    </Attribute>


Databases are typically much more complex. In our example above it would more likely that the Books table contains one or more foreign keys that references the authors of the book. So how to capture this? If we simply add the key field to the Sequence how do users of the system know how to construct queries that can return the data they want? Would this representation allow them to make requests that could return data with the key relationships expressed in the DAP structure (I don't think so)    How do we prevent them from making requests the create problems for the RDBMS by creating, via the DAP constraint expression, unreasonable JOIN requests. Additionally, this very flat representation doesn't clearly establish the relationships between the tables.


On possible solution is to represent the databse tables as a series of nested sequences:


   
Dataset {
    <Attribute name="site_code" type="Container">
        <Attribute name="long_name" type="String">
    Sequence {
            <value>Contributing radar site code</value>
        String Title;
        </Attribute>
        String Publisher;
    </Attribute>
        Int16  Pages;
    <Attribute name="site_netCode" type="Container">
        String   CopyrightDate;
        <Attribute name="long_name" type="String">
        String   ISBN;
            <value>Contributing radar site network affiliation code</value>
        Sequence {
        </Attribute>
            String FirstName;
    </Attribute>
            String LastName;
    <Attribute name="NC_GLOBAL" type="Container">
            String PhoneNumber;
        <Attribute name="netcdf_library_version" type="String">
        } Authors;
            <value>netcdf library version 3.6.1 of Feb 3 2008 23:15:25 $</value>
    } Books;
        </Attribute>
        <Attribute name="format_version" type="String">
} Inventory;
            <value>HFRNet_1.0.0b2</value>
        </Attribute>
        <Attribute name="product_version" type="String">
            <value>HFRNet_1.1.01</value>
        </Attribute>
        <Attribute name="Conventions" type="String">
            <value>CF-1.1</value>
        </Attribute>
        <Attribute name="title" type="String">
            <value>Near-Real Time Surface Ocean Velocity</value>
        </Attribute>
        <Attribute name="institution" type="String">
            <value>Scripps Institution of Oceanography</value>
        </Attribute>
        <Attribute name="source" type="String">
            <value>Surface Ocean HF-Radar</value>
        </Attribute>
        <Attribute name="history" type="String">
            <value>12-Mar-2008 22:26:19: NetCDF file created</value>
        </Attribute>
        <Attribute name="references" type="String">
            <value>Terrill, E. et al., 2006. Data Management and Real-time\\012Distribution in the HF-Radar National
                Network. Proceedings\\012of the MTS/IEEE Oceans 2006 Conference, Boston MA,\\012September 2006.
            </value>
        </Attribute>
        <Attribute name="creator_name" type="String">
            <value>Mark Otero</value>
        </Attribute>
        <Attribute name="creator_email" type="String">
            <value>motero@mpl.ucsd.edu</value>
        </Attribute>
        <Attribute name="creator_url" type="String">
            <value>http://cordc.ucsd.edu/projects/mapping/</value>
        </Attribute>
        <Attribute name="summary" type="String">
            <value>Surface ocean velocities estimated from HF-Radar are\\012representitive of the upper 0.3 - 2.5 meters
                of the\\012ocean. The main objective of near-real time\\012processing is to produce the best product
                from\\012available data at the time of processing. Radial\\012velocity measurements are obtained from
                individual\\012radar sites through the HF-Radar Network and\\012processed to create near-real time
                velocities\\012(RTVs)
            </value>
        </Attribute>
        <Attribute name="geospatial_lat_min" type="Float32">
            <value>21.73596001</value>
        </Attribute>
        <Attribute name="geospatial_lat_max" type="Float32">
            <value>46.49441910</value>
        </Attribute>
        <Attribute name="geospatial_lon_min" type="Float32">
            <value>-97.88385010</value>
        </Attribute>
        <Attribute name="geospatial_lon_max" type="Float32">
            <value>-57.23120880</value>
        </Attribute>
        <Attribute name="grid_resolution" type="String">
            <value>6km</value>
        </Attribute>
        <Attribute name="grid_projection" type="String">
            <value>equidistant cylindrical</value>
        </Attribute>
        <Attribute name="regional_description" type="String">
            <value>Unites States, East and Gulf Coast</value>
        </Attribute>
    </Attribute>
    <Attribute name="DODS_EXTRA" type="Container">
        <Attribute name="Unlimited_Dimension" type="String">
            <value>time</value>
        </Attribute>
    </Attribute>


    <Array name="time">
Does this actually represent the case of foreign keys?
        <Attribute name="standard_name" type="String">
            <value>time</value>
        </Attribute>
        <Attribute name="units" type="String">
            <value>seconds since 1970-01-01</value>
        </Attribute>
        <Attribute name="calendar" type="String">
            <value>gregorian</value>
        </Attribute>
        <Int32/>
        <dimension name="time" size="1"/>
    </Array>
    <Array name="lat">
        <Attribute name="standard_name" type="String">
            <value>latitude</value>
        </Attribute>
        <Attribute name="units" type="String">
            <value>degrees_north</value>
        </Attribute>
        <Float32/>
        <dimension name="lat" size="460"/>
    </Array>
    <Array name="lon">
        <Attribute name="standard_name" type="String">
            <value>longitude</value>
        </Attribute>
        <Attribute name="units" type="String">
            <value>degrees_east</value>
        </Attribute>
        <Float32/>
        <dimension name="lon" size="701"/>
    </Array>
    <Grid name="u">
        <Attribute name="standard_name" type="String">
            <value>surface_eastward_sea_water_velocity</value>
        </Attribute>
        <Attribute name="units" type="String">
            <value>m s-1</value>
        </Attribute>
        <Attribute name="_FillValue" type="Int16">
            <value>-32768</value>
        </Attribute>
        <Attribute name="scale_factor" type="Float32">
            <value>0.009999999776</value>
        </Attribute>
        <Attribute name="ancillary_variables" type="String">
            <value>DOPx</value>
        </Attribute>
        <Array name="u">
            <Int16/>
            <dimension name="time" size="1"/>
            <dimension name="lat" size="460"/>
            <dimension name="lon" size="701"/>
        </Array>
        <Map name="time">
            <Int32/>
            <dimension name="time" size="1"/>
        </Map>
        <Map name="lat">
            <Float32/>
            <dimension name="lat" size="460"/>
        </Map>
        <Map name="lon">
            <Float32/>
            <dimension name="lon" size="701"/>
        </Map>
    </Grid>
    <Grid name="v">
        <Attribute name="standard_name" type="String">
            <value>surface_northward_sea_water_velocity</value>
        </Attribute>
        <Attribute name="units" type="String">
            <value>m s-1</value>
        </Attribute>
        <Attribute name="_FillValue" type="Int16">
            <value>-32768</value>
        </Attribute>
        <Attribute name="scale_factor" type="Float32">
            <value>0.009999999776</value>
        </Attribute>
        <Attribute name="ancillary_variables" type="String">
            <value>DOPy</value>
        </Attribute>
        <Array name="v">
            <Int16/>
            <dimension name="time" size="1"/>
            <dimension name="lat" size="460"/>
            <dimension name="lon" size="701"/>
        </Array>
        <Map name="time">
            <Int32/>
            <dimension name="time" size="1"/>
        </Map>
        <Map name="lat">
            <Float32/>
            <dimension name="lat" size="460"/>
        </Map>
        <Map name="lon">
            <Float32/>
            <dimension name="lon" size="701"/>
        </Map>
    </Grid>
    <Grid name="DOPx">
        <Attribute name="long_name" type="String">
            <value>longitudinal dilution of precision</value>
        </Attribute>
        <Attribute name="comment" type="String">
            <value>The longitudinal dilution of precision (DOPx) represents the\\012contribution of the radars&apos;
                configuration geometry to\\012uncertainty in the eastward velocity estimate (u). DOPx is a\\012direct
                multiplier of the standard error in obtaining the\\012standard deviation for the eastward velocity
                estimate from the\\012least squares best fit. DOPx and DOPy are commonly used to\\012obtain the
                geometric dilution of precision\\012(GDOP = sqrt(DOPx^2 + DOPy^2)), a useful metric for
                filtering\\012errant velocities due to poor geometry.
            </value>
        </Attribute>
        <Attribute name="_FillValue" type="Int16">
            <value>-32768</value>
        </Attribute>
        <Attribute name="scale_factor" type="Float32">
            <value>0.009999999776</value>
        </Attribute>
        <Array name="DOPx">
            <Int16/>
            <dimension name="time" size="1"/>
            <dimension name="lat" size="460"/>
            <dimension name="lon" size="701"/>
        </Array>
        <Map name="time">
            <Int32/>
            <dimension name="time" size="1"/>
        </Map>
        <Map name="lat">
            <Float32/>
            <dimension name="lat" size="460"/>
        </Map>
        <Map name="lon">
            <Float32/>
            <dimension name="lon" size="701"/>
        </Map>
    </Grid>
    <Grid name="DOPy">
        <Attribute name="long_name" type="String">
            <value>latitudinal dilution of precision</value>
        </Attribute>
        <Attribute name="comment" type="String">
            <value>The latitudinal dilution of precision (DOPy) represents the\\012contribution of the radars&apos;
                configuration geometry to\\012uncertainty in the northward velocity estimate (v). DOPy is a\\012direct
                multiplier of the standard error in obtaining the\\012standard deviation for the northward velocity
                estimate from the\\012least squares best fit. DOPx and DOPy are commonly used to\\012obtain the
                geometric dilution of precision\\012(GDOP = sqrt(DOPx^2 + DOPy^2)), a useful metric for
                filtering\\012errant velocities due to poor geometry.
            </value>
        </Attribute>
        <Attribute name="_FillValue" type="Int16">
            <value>-32768</value>
        </Attribute>
        <Attribute name="scale_factor" type="Float32">
            <value>0.009999999776</value>
        </Attribute>
        <Array name="DOPy">
            <Int16/>
            <dimension name="time" size="1"/>
            <dimension name="lat" size="460"/>
            <dimension name="lon" size="701"/>
        </Array>
        <Map name="time">
            <Int32/>
            <dimension name="time" size="1"/>
        </Map>
        <Map name="lat">
            <Float32/>
            <dimension name="lat" size="460"/>
        </Map>
        <Map name="lon">
            <Float32/>
            <dimension name="lon" size="701"/>
        </Map>
    </Grid>
    <Array name="site_lat">
        <Attribute name="long_name" type="String">
            <value>Contributing radar site latitudes</value>
        </Attribute>
        <Attribute name="standard_name" type="String">
            <value>latitude</value>
        </Attribute>
        <Attribute name="units" type="String">
            <value>degrees_north</value>
        </Attribute>
        <Float32/>
        <dimension name="nSites" size="27"/>
    </Array>
    <Array name="site_lon">
        <Attribute name="long_name" type="String">
            <value>Contributing radar site longitudes</value>
        </Attribute>
        <Attribute name="standard_name" type="String">
            <value>longitude</value>
        </Attribute>
        <Attribute name="units" type="String">
            <value>degrees_east</value>
        </Attribute>
        <Float32/>
        <dimension name="nSites" size="27"/>
    </Array>
    <Array name="procParams">
        <Attribute name="long_name" type="String">
            <value>RTV processing parameters</value>
        </Attribute>
        <Attribute name="comment" type="String">
            <value>\\01201) Maximum GDOP threshold\\01202) Maximum speed threshold (cm s-1)\\01203) Minimum number of
                sites required\\01204) Minimum number of radials required\\01205) Maximum angular gap to interpolate
                radial\\012 data over (degrees, 0 = no interpolation)\\01206) Maximum gap in range to interpolate
                radial\\012 data over (range-resolution, 0 = no interpolation)\\01207) Spatial search radius for radial
                solutions (km)
            </value>
        </Attribute>
        <Float32/>
        <dimension name="nProcParam" size="7"/>
    </Array>


</Dataset>
=== Tasks ===
</pre>


==== XSLT ====
A server that adds a DAP interface to a RDBMS needs:


<pre>
# A component that can translate a DAP query into an SQL query string. This might happen at the string level by simply converting one to the other. The DRDS accomplished this by processing the DAP query string (marking variables in a DDS instance as projected and parsing the selection part of the constraint into Clause objects) and then working with the in memory objects (DDS and Clause objects) to build the SQL query.
<?xml version="1.0" encoding="ISO-8859-1"?>
#  A mechanism through which the RDBMS holdings (a collection of one or more tables and views) can be represented as a collection of DAP data sets. For this document we will refer to this as ''catalog'' generation. This is inexorably connected to the ''type mapping'' activities explained next.
<!--
# A mapping between the data types found in the RDBMS to the appropriate DAP data types. For many simple/atomic type this is simple: An SQL FLOAT maps naturally to a DAP Float64. For other types, such as an database table with foreign keys the mapping is less straightforward. This activity s further complicated by the fact that nearly every RDBMS implementation contains a number of useful, yet proprietary data types. Thus a proper data model might have to be generated for each RDBMS encountered.
/////////////////////////////////////////////////////////////////////////////
// This file is part of the "OPeNDAP 4 Data Server (aka Hyrax)" project.
//
//
// Copyright (c) 2008 OPeNDAP, Inc.
// Author: Nathan David Potter  <ndp@opendap.org>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
/////////////////////////////////////////////////////////////////////////////
-->
<!DOCTYPE xsl:stylesheet [
        <!ENTITY DAPOBJ  "http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#" >
        <!ENTITY DAP     "http://xml.opendap.org/ns/DAP/3.3#" >
        <!ENTITY XSD    "http://www.w3.org/2001/XMLSchema#" >
        ]>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xmlns:cf="http://iridl.ldeo.columbia.edu/ontologies/cf-att.owl#"
                xmlns:dapObj="&DAPOBJ;"
                xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
                xmlns:owl="http://www.w3.org/2002/07/owl#"
                xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
                xmlns:dap="&DAP;"
                xmlns:xml="http://www.w3.org/XML/1998/namespace"


        >
=== Previous Design/Implementation ===
    <xsl:output method='xml' version='1.0' encoding='UTF-8' indent='yes'/>
    <xsl:key name="AttributeNames" match="dap:Attribute" use="@name"/>


    <xsl:variable name="XML_BASE"><xsl:value-of select="/dap:Dataset/@xml:base"/></xsl:variable>
The first DRDS (DODS Relational Database Server) was implemented as a Java Servlet. It relied on the Java-DODS implementation of the DAP to provide the DAP type classes with constraint expression evaluation and data value serialization.
    <xsl:variable name="LocalOntology"><xsl:value-of select="$XML_BASE"/>.rdf</xsl:variable>
Some documentation can be found here:  
    <xsl:variable name="LocalAttributeNS"><xsl:value-of select="$XML_BASE"/>/att#</xsl:variable>
* [http://www.opendap.org/design/java-api/design.html General Java DAP Implementation Documents]
* [http://scm.opendap.org/svn/trunk/DRDS/ DRDS source tree]




    <xsl:strip-space elements="*"/>
Important features/activities:


    <!-- ###################################################################
* The server used filesystem directories containing DDS and DAS documents to represent the holdings in the RDBMS. These files were used to generate the DDS and DAS responses.
      -
* The opendap.servers.sql.sqlCEEval.getSQLQueries() method that takes a constrained DDS object and interrogates it to form an SQL query.  
      -  Converts a Dataset DDX into an RDF Document.
* Each table or view in the database could only be represented as a data set containing a singe DAP Sequence.
      -
* The individual DAP type classes implement the read() and serialize() methods that extracts values from the SQL query result and write the values to the client. The DAP Sequence implementation manages which "row" is being read from the SQL response object.
    -->
    <xsl:template match="/dap:Dataset">


        <rdf:RDF>
Despite its limitations and lack of ongoing support the DRDS was useful for a number of data centers and continues to be used today. However, the DRDS had many drawbacks:
            <xsl:attribute name="base" namespace="http://www.w3.org/XML/1998/namespace">
                <xsl:value-of select="$XML_BASE"/>
            </xsl:attribute>


            <owl:Ontology
* It required the operator to engage in a significant configuration steps:
                    rdf:about="{$LocalOntology}">
** Locating a JDBC driver for their database implementation.
                <owl:imports
** Configuring the DRDS to correctly use the JDBC driver.
                        rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl"/>
**  Hand writing the DDS and DAS documents for each table or view in the database for which DAP 2 services were to be provided. This in effect placed the operator of the server in charge of mapping the different types of data held in the database tables into the different types in the DAP data model. The DRDS implementation only allowed certain mappings (as many of the possible combinations were non-sensical), thus if the operator made a poor mapping (For example creating a floating point variable in the DDS and then trying to read a SQL CHAR type into it) the server would not function correctly.
                <owl:imports
* It could not automatically build a catalog of the RDBMS holdings. (This was done by the operator as described above)
                        rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/NetcdfConventionRegistry.owl"/>
* The representation of the RDBMS holds was limited to a single table per DAP data set. Thus each DDS in the catalog contained a single Sequence representing a single table or view from within the RDBMS. Since most RDBMS holds are a collection of tables linked together through keys, this single Sequence representation was a very "flat" view of the RDBMS which many users found particularly restrictive. Making different views of the database alleviated the effects of this limitation to a certain extent, but typically caused some (many?) data values to be sent in a repetitive manner.
            </owl:Ontology>


            <!-- The empty rdf:about defaults to the value of @xml:base -->
== Data model representation ==
            <dapObj:Dataset rdf:about="">


                <rdfs:isDefinedBy rdf:resource="{$LocalOntology}"/>
Mapping the a the SQL data model to the DAP data model is problematic due to the diversity of the implementations of an SQL database.


                <dapObj:dataset_id rdf:datatype="http://www.w3.org/2001/XMLSchema#string">
                    <xsl:value-of select="@dataset_id"/>
                </dapObj:dataset_id>


                <xsl:apply-templates select="*" mode="body"/>
            </dapObj:Dataset>


            <xsl:call-template name="AttPropDef"/>
=== Atomic (Simple) Types ===


        </rdf:RDF>
    </xsl:template>
    <!-- ################################################################### -->


=== Tables as Sequences ===


    <!-- ###################################################################
==== Single Tables ====
    -
    -
    -    Body of content. ( mode="body" )
    -
    -
    -->
    <xsl:template match="dap:Attribute" mode="body">


==== Multiple Tables ====


        <xsl:choose>
==== Multiple Tables as Nested Sequences ====


            <xsl:when test="@type='Container'">
=== Other Complex Types ===
                <xsl:element name="att:{@name}" namespace="{$LocalAttributeNS}">
                    <xsl:attribute name="rdf:parseType">Resource</xsl:attribute>
                    <xsl:apply-templates select="./*" mode="body"/>
                </xsl:element>
            </xsl:when>


            <xsl:when test="@type='OtherXML'">
== Relational Database Data Types ==
                <xsl:apply-templates select="*" mode="OtherXML">
                    <xsl:with-param name="relationship" select="@relationship"/>
                </xsl:apply-templates>
            </xsl:when>


            <xsl:otherwise>
Accessing data in an RDBMS is often a many layered affair. Many RDBMS implementations provide a native API library that can be used with a common programming language such as C, C++, C#, Visual Basic, or even Java. These API's interact directly with the RDBMS and provide the maximum level of flexibility, control and access. If one was using a native API to work with a RDBMS to get data then there would be a mapping from the native RDBMS data types to the language data types:


                <xsl:element name="att:{@name}" namespace="{$LocalAttributeNS}">


                    <xsl:if test="dap:value[last()=1]">
:''Native RDBMS Data Types'' '''--->''' ''C++ Data Types''
                        <xsl:call-template name="attributeType">
                            <xsl:with-param name="thisAttribute" select="."/>
                        </xsl:call-template>
                        <!-- <xsl:comment> Single Value </xsl:comment> -->


                        <xsl:value-of select="."/>


                    </xsl:if>
However, most software that works with RDMSs does so through a database connectivity API. The two most common are the Open Database Connectivity (ODBC) API and the Java Database Connectivity (JDBC) API. Using one of these database connectivity APIs adds a layer of data type mapping to the process:


                    <xsl:if test="dap:value[last()>1]">
                        <xsl:attribute name="rdf:parseType">Resource</xsl:attribute>
                        <!-- <xsl:comment> Multi Value </xsl:comment> -->


                        <xsl:call-template name="attributeValues">
:''Native RDBMS Data Types'' '''--->''' ''Database Connectivity API  Data Types'' '''--->''' ''C++ Data Types''
                            <xsl:with-param name="values" select="dap:value"/>
                        </xsl:call-template>


                    </xsl:if>


                </xsl:element>
To complete the picture, generating DAP data objects requires the finally mapping from the programming language data types in to the DAP data model:


            </xsl:otherwise>


        </xsl:choose>
:''Native RDBMS Data Types'' '''--->''' ''Database Connectivity API  Data Types'' '''--->''' ''C++ Data Types'' '''--->''' ''DAP Data Types''




    </xsl:template>
For simple/atomic types such as integers an booleans this doesn't require much thought. For more complex types it may require both thought ad careful development to preserve the original semantics of the RDBMS data type across the various mappings and into the appropriate DAP data type. Even then the DAP data model may not have a data type that directly captures the semantics of the original type. For example PostgreSQL has a number of geometric types (such as ''point'', ''box'', and ''circle'') whose content can be held in DAP types, but the semantic meaning (''these two floating point values represent a point on a cartesian plain'') is not explicit in the DAP object holding the values. That information can only be included in the metadata associated with the instance of the DAP variable.


    <!--
    - This helper template uses recursion to process the dap:value elements of a dap:Attribute
    - into an ordered list of RDF literals, which given the current state of RDF
    - isn't a very pretty thing.
    -->


    <xsl:template name="attributeValues">




        <xsl:param name="values"/>
=== Database Connectivity APIs ===


        <!--
<br/><br/>
                <xsl:comment>############################################</xsl:comment>
----
                <xsl:comment>                                            </xsl:comment>
----
                <xsl:comment> values                                  </xsl:comment>
==== [http://en.wikipedia.org/wiki/Open_Database_Connectivity ODBC Data Types] ====
                <xsl:copy-of select="$values" />
                <xsl:comment>                                            </xsl:comment>
                <xsl:comment>############################################</xsl:comment>


        -->
<br/><br/>
        <rdf:first>
----
            <xsl:call-template name="attributeType">
----
                <xsl:with-param name="thisAttribute" select="$values[1]/.."/>
==== [http://java.sun.com/javase/technologies/database/ JDBC Data Types] ====
            </xsl:call-template>
            <xsl:value-of select="$values[1]"/>
        </rdf:first>
        <rdf:rest>


            <xsl:if test="boolean($values[position()>1])">
The DRDS used a JDBC connection to retrieve data from a relational database. It is important to note that their are several layers of type translation happening in this:
                <xsl:attribute name="rdf:parseType">Resource</xsl:attribute>
:'''Database -> JDBC -> Java -> DODS'''
                <xsl:call-template name="attributeValues">
The Database types are the native types for the particular database that is being read from. The translation from Database->JDBC was handled before the data arrived at the DRDS (most likely by the JDBC Drivers). The mapping of JDBC type to DODS types (the intermediate Java types happen in the process) looked like this:
                    <xsl:with-param name="values" select="$values[position()>1]"/>
                </xsl:call-template>
            </xsl:if>


            <xsl:if test="not(boolean($values[position()>1]))">
{| align="center" border="1" cellspacing="0" width="75%"
                <xsl:attribute name="rdf:resource">http://www.w3.org/1999/02/22-rdf-syntax-ns#nil</xsl:attribute>
|+'''Mapping from JDBC Types to DODS Types'''
            </xsl:if>
! JDBC Type !! DAP Type
|-
| TINYINT || DByte
|-
|  SMALLINT  ||    DInt16
|-
|  INTEGER  ||      DInt32
|-
|  BIGINT  ||        DInt32  **NO SENSIBLE MAPPING (Need DInt64)
|-
|  REAL    ||      DFloat32
|-
|  FLOAT    ||      DFloat64
|-
|  DOUBLE  ||      DFloat64
|-
|  DECIMAL ||        DFloat64 **NO SENSIBLE MAPPING (Need Some Kind Monsterous Floating point value)
|-
|  NUMERIC ||      DFloat64 **NO SENSIBLE MAPPING (ibid)
|-
|  BIT  ||          DBoolean
|-
|  CHAR  ||        DString
|-
|  VARCHAR  ||      DString
|-
|    LONGVARCHAR ||    Implemented to be read into a DString, although it is a "BLOB" type  and might be better represented as a DArray(of bytes).
|-
|    BINARY    ||      DArray(of bytes)
|-
|    VARBINARY    ||  DArray(of bytes)
|-
|    LONGVARBINARY ||  DArray(of bytes)
|-
|    DATE    ||      DString
|-
|    TIME  ||        DString
|-
|    TIMESTAMP    ||  DString
|}


=== Native SQL Data Types by Implementation ===


        </rdf:rest>


    </xsl:template>
<br/><br/>
----
----
==== [http://www.postgresql.org/docs/8.3/interactive/datatype.html PostgreSQL Data Types] ====
:'''Todo:'''
::'''<font color=red> !! This section needs to be updated and otherwise corrected. !!</font>'''


===== Boolean and Binary Types =====
{| border="1" cellspacing="0"
! Data Type  !! Description !! Standardization || Logical DAP data type association.
|-
| boolean, bool ||  A single true or false value. || SQL99 || Boolean
|-
| bit(n) || An n -length bit string (exactly n binary bits). || SQL92 || ''None''
|-
| bit varying(n), varbit(n) || A variable n -length bit string (up to n binary bits) || SQL92 || ''None''
|}


    <xsl:template name="attributeType">
===== Character Types =====
{| border="1" cellspacing="0"
! Data Type  !! Description !! Storage !! Standardization || Logical DAP data type association.
|-
| character (n ), char(n ) ||A fixed n -length character string.|| (4+n) bytes|| SQL89 || String
|-
| character varying(n), varchar(n) || A variable length character string of up to n characters. || Up to (4+n) bytes || SQL92 || String
|-
| text || A variable length character string, of unlimited length. || Variable || PostgreSQL-specific || String
|}


        <xsl:param name="thisAttribute"/>
===== Numeric Types =====
        <xsl:attribute name="rdf:datatype">
{| border="1" cellspacing="0"
            <xsl:if test="$thisAttribute/@type='Byte'">&XSD;byte</xsl:if>
! Data Type  !! Description !! Storage !! Standardization || Logical DAP data type association.
            <xsl:if test="$thisAttribute/@type='Int16'">&XSD;short</xsl:if>
|-
            <xsl:if test="$thisAttribute/@type='UInt16'">&XSD;unsignedShort</xsl:if>
| smallint, int2 || A signed 2-byte integer || 2 bytes || SQL89 || Int16
            <xsl:if test="$thisAttribute/@type='Int32'">&XSD;long</xsl:if>
|-
            <xsl:if test="$thisAttribute/@type='UInt32'">&XSD;unsignedLong</xsl:if>
| integer, int, int4 || A signed, fixed-precision 4-byte number. || 4 bytes || SQL92 || Int32
            <xsl:if test="$thisAttribute/@type='Float32'">&XSD;float</xsl:if>
|-
            <xsl:if test="$thisAttribute/@type='Float64'">&XSD;double</xsl:if>
| bigint, int8 || A signed 8-byte integer, up to 18 digits in length. || 8 bytes || PostgreSQL-specific || ''None (Need Int64)''
            <xsl:if test="$thisAttribute/@type='String'">&XSD;string</xsl:if>
|-
            <xsl:if test="$thisAttribute/@type='Url'">&XSD;anyURI</xsl:if>
| real, float4 || A 4-byte floating point number. || 4 bytes ||  SQL89 || Float32
        </xsl:attribute>
|-
| double precision, float8, float || An 8-byte floating point number || 8 bytes || SQL89 || Float64
|-
| numeric(p,s), decimal(p,s) || An exact numeric type with arbitrary precision p, and scale s. || Variable || SQL99 || ''None''
|-
| money || A fixed precision, U.S.-style currency. || 4 bytes || PostgreSQL-specific, deprecated. || ''None''
|-
| serial || An auto-incrementing 4-byte integer. || 4 bytes || PostgreSQL-specific. || ''None''
|}


    </xsl:template>
===== Date and Time Types =====
{| border="1" cellspacing="0"
! Data Type  !! Description !! Storage !! Standardization || Logical DAP data type association.
|-
| date || A calendar date (day, month, year). || 4 bytes ||  SQL92 || ''String''
|-
| time || The time of day. || 4 bytes || SQL92 || ''String''
|-
| time with time zone || The time of day, including time zone information. || 4 bytes || SQL92 || ''String''
|-
| timestamp (includes time zone) || Both date and time. || 8 bytes || SQL92 || ''String''
|-
| interval || An arbitrary specified length of time || 12 bytes || SQL92 || ''String''
|}


===== Geometric Types =====
{| border="1" cellspacing="0"
! Data Type  !! Description !! Storage !! Standardization || Logical DAP data type association.
|-
| box || A rectangular box in a 2D plane. || 32 bytes || PostgreSQL-specific || ''None'' ([2][2] Array of Float32)
|-
| line || An infinite line in a 2D plane. || ?? bytes || PostgreSQL-specific || ''None'' ([2][2] Array of Float32)
|-
| lineseg ||A finite line segment in a 2D plane. || 32 bytes ||  PostgreSQL-specific || ''None'' ([2][2] Array of Float32)
|-
| circle || A circle with center and radius. || 24 bytes || PostgreSQL-specific || ''None'' ([3]Array of Float32)
|-
| path ||  Open and closed geometric paths in a two-dimensional plane . || 4+32*n  bytes || PostgreSQL-specific || ''None'' (Array of Float32)
|-
| point || geometric point in a 2D plane || 16 bytes || PostgreSQL-specific || ''None''  ([2] Array of Float32)
|-
| polygon || A closed geometric path in a 2D plane || 4+32*n bytes || PostgreSQL-specific || ''None'' (Array of Float32)
|}


    <!--
===== Network Types =====
    -  mode="anyXMLToRDF"
{| border="1" cellspacing="0"
    -
! Data Type  !! Description !! Standardization || Logical DAP data type association.
    - Maps the OtherXML dap:Attribute type to RDF while expressing the appropriate relationship
|-
    - of the XML to the parent DAP object.
| cdir || An IP network specification || PostgreSQL-specific || ''None''
    -
|-
    -
| inet || A network IP address, with optional subnet bits.  || PostgreSQL-specific || ''None''
    -
|-
    -->
| macaddr || A MAC address (e.g., an Ethernet card's hardware address). || PostgreSQL-specific || ''None''
    <xsl:template name="OtherXML" match="*" mode="OtherXML">
|}
        <xsl:param name="relationship"/>


        <xsl:choose>
===== System  Types =====
{| border="1" cellspacing="0"
! Data Type  !! Description !! Standardization || Logical DAP data type association.
|-
| oid || An object (row) identifier. || PostgreSQL-specific || ''None''
|-
| xid || A transaction identifier  || PostgreSQL-specific || ''None''
|}
<br /><br />
----
----
==== [http://msdn.microsoft.com/en-us/library/ms187752.aspx Transact-SQL (Microsoft)] ====
:'''Todo:'''
::'''<font color=red> !! This section needs to be updated and otherwise corrected. !!</font>'''


            <xsl:when test="boolean($relationship) and $relationship='is-a'">
{| border="1" cellspacing="0"
                <xsl:apply-templates select="." mode="anyXMLToRDF"/>
!Type !! Description !! Storage Bytes !! DAP equiv.
            </xsl:when>
|-
            <xsl:when test="boolean($relationship) and $relationship='has-a'">
|bigint ||Integer (whole number) data from -2^63 (-9,223,372,036,854,775,808) through 2^63-1 (9,223,372,036,854,775,807).  || 8 bytes || none
                <HAS-A>
|-
                    <xsl:copy-of select="."/>
|int ||Integer (whole number) data from -2^31 (-2,147,483,648) through 2^31 - 1 (2,147,483,647). || 4 bytes ||
                </HAS-A>
|-
            </xsl:when>
|numeric || Functionally equivalent to decimal. || ||
            <xsl:otherwise>
|-
                <HAS-A>
|decimal || Fixed precision and scale numeric data from -10^38 +1 through 10^38 –1.  || ||
                    <xsl:copy-of select="."/>
|-
| bit || Integer data with either a 1 or 0 value  || ||
|-
|smallint || Integer data from -2^15 (-32,768) through 2^15 - 1 (32,767).  ||  2 bytes ||
|-
|tinyint || Integer data from 0 through 255  || 1 bytes||
|-
| smallmoney  || Monetary data values from -214,748.3648 through +214,748.3647, with accuracy to a ten-thousandth of a monetary unit. ||  ||
|-
| money  || Monetary data values from -2^63 (-922,337,203,685,477.5808) through 2^63 - 1 (+922,337,203,685,477.5807), with accuracy to a ten-thousandth of a monetary unit. || ||
|-
| float || Floating precision number data with the following valid values: -1.79E + 308 through -2.23E - 308, 0 and 2.23E + 308 through 1.79E + 308. || 4 or 8 bytes ||
|-
| real  || Floating precision number data with the following valid values: -3.40E + 38 through -1.18E - 38, 0 and 1.18E - 38 through 3.40E + 38. || 4 bytes ||
|-
| date  || ||  ||
|-
| datetimeoffset  || ||  ||
|-
| datetime2  || ||  ||
|-
| smalldatetime  || Date and time data from January 1, 1900, through June 6, 2079, with an accuracy of one minute.  ||  ||
|-
| datetime  || Date and time data from January 1, 1753, through December 31, 9999, with an accuracy of three-hundredths of a second, or 3.33 milliseconds. ||  ||
|-
| time  || ||  ||
|-
| char  || Fixed-length non-Unicode character data with a maximum length of 8,000 characters. ||  ||
|-
| varchar  || Variable-length non-Unicode data with a maximum of 8,000 characters. ||  ||
|-
| next  || Variable-length non-Unicode data with a maximum length of 2^31 - 1 (2,147,483,647) characters ||  ||
|-
| nchar  || Fixed-length Unicode data with a maximum length of 4,000 characters  ||  ||
|-
| nvarchar  || Variable-length Unicode data with a maximum length of 4,000 characters. sysname is a system-supplied user-defined data type that is functionally equivalent to nvarchar(128) and is used to reference database object names.  ||  ||
|-
| ntext  || Variable-length Unicode data with a maximum length of 2^30 - 1 (1,073,741,823) characters.  ||  ||
|-
| binary  || Fixed-length binary data with a maximum length of 8,000 bytes. ||  ||
|-
| varbinary  || Variable-length binary data with a maximum length of 8,000 bytes. ||  ||
|-  
| image  || Variable-length binary data with a maximum length of 2^31 - 1 (2,147,483,647) bytes.  ||  ||
|-
| cursor  || A reference to a cursor.||  ||
|-  
| timestamp  || A database-wide unique number that gets updated every time a row gets updated. ||  ||
|-
| hierarchyid  || ||  ||
|-  
| uniquieidentifier  || A globally unique identifier (GUID). ||  ||
|-
| sql_variant  || ||  ||
|-
| xml  || ||  ||
|-  
| table  || ||  ||
|}


                </HAS-A>
== Template ==
            </xsl:otherwise>
==== Types ====
        </xsl:choose>
{| border="1" cellspacing="0"
! Data Type  !! Description !! Standardization || Logical DAP data type association.
|-
|
|-
|
|-
|
|}


    </xsl:template>
== Desired Features ==


 
== Implementation Target ==
    <!--
    -  mode="anyXMLToRDF"
    -
    -  Map arbitrary XML (OtherXML) into RDF.
    -
    -
    -
    -
    -->
 
 
    <xsl:template name="textAndattributes">
        <xsl:copy-of select="text()|@*"/>
    </xsl:template>
 
 
    <xsl:template match="@*|text()" mode="anyXMLToRDF"/>
    <xsl:template match="*" mode="anyXMLToRDF">
 
        <rdf:type>
            <xsl:apply-templates select="." mode="anyXMLToRDFWorker"/>
        </rdf:type>
 
    </xsl:template>
 
 
    <xsl:template match="@*|text()" mode="anyXMLToRDFWorker"/>
    <xsl:template match="*" mode="anyXMLToRDFWorker">
        <xsl:choose>
            <xsl:when test="*">
                <xsl:copy>
 
                    <!-- XML Attributes with namespaces-->
                    <xsl:for-each select="@*[namespace-uri()!='']">
                        <xsl:attribute name="{local-name()}" namespace="{namespace-uri()}">
                            <xsl:value-of select="."/>
                        </xsl:attribute>
                    </xsl:for-each>
 
                    <!-- XML Attributes without namespaces-->
                    <xsl:for-each select="@*[namespace-uri()='']">
                        <xsl:apply-templates select="." mode="xmlAttributeNode"/>
                    </xsl:for-each>
 
                    <!-- XML Text -->
                    <xsl:apply-templates select="text()" mode="xmlTextNode"/>
 
 
                    <!-- XML Child Elements -->
                    <xsl:for-each select="*">
                        <xsl:choose>
                            <!-- Child Elements with children elements -->
                            <xsl:when test="*">
                                <dapObj:xmlContains>
                                    <xsl:apply-templates select="." mode="anyXMLToRDFWorker"/>
                                </dapObj:xmlContains>
                            </xsl:when>
 
                            <!-- Simple Children -->
                            <xsl:otherwise>
                                <xsl:apply-templates select="." mode="anyXMLToRDFWorker"/>
                            </xsl:otherwise>
                        </xsl:choose>
                    </xsl:for-each>
 
                </xsl:copy>
 
            </xsl:when>
            <xsl:otherwise>
                <xsl:copy-of select="."/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
 
 
    <xsl:template match="@*" mode="xmlTextNode"/>
 
    <xsl:template match="text()" mode="xmlTextNode">
        <dapObj:xmlText>
            <xsl:value-of select="."/>
        </dapObj:xmlText>
    </xsl:template>
 
 
    <xsl:template match="text()" mode="xmlAttributeNode"/>
 
    <xsl:template match="@*" mode="xmlAttributeNode">
        <dapObj:xmlAttribute dapObj:name="{local-name()}" rdf:value="{.}"/>
    </xsl:template>
 
 
    <!--
        <xsl:template match="dap:dataBLOB" mode="body">
            <dapObj:hasdataBLOB>
                <dap:dataBLOB rdf:about="{@href}"/>
            </dapObj:hasdataBLOB>
        </xsl:template>
    -->
 
    <xsl:template match="dap:Grid" mode="body">
        <dapObj:isContainerOf>
            <dap:Grid>
                <xsl:attribute name="rdf:ID">
                    <xsl:call-template name="localIdWorker"/>
                </xsl:attribute>
                <xsl:apply-templates select="dap:Attribute" mode="body"/>
 
                <xsl:apply-templates select="dap:Array" mode="body"/>
                <xsl:apply-templates select="dap:Map" mode="body"/>
 
                <xsl:call-template name="localId"/>
 
            </dap:Grid>
        </dapObj:isContainerOf>
    </xsl:template>
 
 
    <xsl:template match="dap:Structure" mode="body">
        <dapObj:isContainerOf>
            <dap:Structure>
                <xsl:attribute name="rdf:ID">
                    <xsl:call-template name="localIdWorker"/>
                </xsl:attribute>
 
                <xsl:apply-templates mode="body"/>
 
                <xsl:call-template name="localId"/>
            </dap:Structure>
        </dapObj:isContainerOf>
    </xsl:template>
 
 
    <xsl:template match="dap:Sequence" mode="body">
        <dapObj:isContainerOf>
            <dap:Sequence>
                <xsl:attribute name="rdf:ID">
                    <xsl:call-template name="localIdWorker"/>
                </xsl:attribute>
 
                <xsl:apply-templates mode="body"/>
 
                <xsl:call-template name="localId"/>
            </dap:Sequence>
        </dapObj:isContainerOf>
    </xsl:template>
 
 
    <xsl:template match="dap:Array" mode="body">
        <dapObj:isContainerOf>
            <xsl:apply-templates mode="array"/>
        </dapObj:isContainerOf>
    </xsl:template>
 
    <xsl:template match="dap:Map" mode="body">
        <dapObj:hasMap>
            <xsl:apply-templates mode="array"/>
        </dapObj:hasMap>
    </xsl:template>
 
 
    <xsl:template match="dap:Byte" mode="body">
        <dapObj:isContainerOf>
            <dap:Byte>
                <xsl:attribute name="rdf:ID">
                    <xsl:call-template name="localIdWorker"/>
                </xsl:attribute>
                <xsl:apply-templates select="dap:Attribute" mode="body"/>
                <xsl:call-template name="localId"/>
            </dap:Byte>
        </dapObj:isContainerOf>
    </xsl:template>
 
    <xsl:template match="dap:Int16" mode="body">
        <dapObj:isContainerOf>
            <dap:Int16>
                <xsl:attribute name="rdf:ID">
                    <xsl:call-template name="localIdWorker"/>
                </xsl:attribute>
                <xsl:apply-templates select="dap:Attribute" mode="body"/>
                <xsl:call-template name="localId"/>
            </dap:Int16>
        </dapObj:isContainerOf>
    </xsl:template>
 
    <xsl:template match="dap:UInt16" mode="body">
        <dapObj:isContainerOf>
            <dap:UInt16>
                <xsl:attribute name="rdf:ID">
                    <xsl:call-template name="localIdWorker"/>
                </xsl:attribute>
                <xsl:apply-templates select="dap:Attribute" mode="body"/>
                <xsl:call-template name="localId"/>
            </dap:UInt16>
        </dapObj:isContainerOf>
    </xsl:template>
 
    <xsl:template match="dap:Int32" mode="body">
        <dapObj:isContainerOf>
            <dap:Int32>
                <xsl:attribute name="rdf:ID">
                    <xsl:call-template name="localIdWorker"/>
                </xsl:attribute>
                <xsl:apply-templates select="dap:Attribute" mode="body"/>
                <xsl:call-template name="localId"/>
            </dap:Int32>
        </dapObj:isContainerOf>
    </xsl:template>
 
    <xsl:template match="dap:UInt32" mode="body">
        <dapObj:isContainerOf>
            <dap:UInt32>
                <xsl:attribute name="rdf:ID">
                    <xsl:call-template name="localIdWorker"/>
                </xsl:attribute>
                <xsl:apply-templates select="dap:Attribute" mode="body"/>
                <xsl:call-template name="localId"/>
            </dap:UInt32>
        </dapObj:isContainerOf>
    </xsl:template>
 
    <xsl:template match="dap:Float32" mode="body">
        <dapObj:isContainerOf>
            <dap:Float32>
                <xsl:attribute name="rdf:ID">
                    <xsl:call-template name="localIdWorker"/>
                </xsl:attribute>
                <xsl:apply-templates select="dap:Attribute" mode="body"/>
                <xsl:call-template name="localId"/>
            </dap:Float32>
        </dapObj:isContainerOf>
    </xsl:template>
 
    <xsl:template match="dap:Float64" mode="body">
        <dapObj:isContainerOf>
            <dap:Float64>
                <xsl:attribute name="rdf:ID">
                    <xsl:call-template name="localIdWorker"/>
                </xsl:attribute>
                <xsl:apply-templates select="dap:Attribute" mode="body"/>
                <xsl:call-template name="localId"/>
            </dap:Float64>
        </dapObj:isContainerOf>
    </xsl:template>
 
    <xsl:template match="dap:String" mode="body">
        <dapObj:isContainerOf>
            <dap:String>
                <xsl:attribute name="rdf:ID">
                    <xsl:call-template name="localIdWorker"/>
                </xsl:attribute>
                <xsl:apply-templates select="dap:Attribute" mode="body"/>
                <xsl:call-template name="localId"/>
            </dap:String>
        </dapObj:isContainerOf>
    </xsl:template>
 
    <xsl:template match="dap:Url" mode="body">
        <dapObj:isContainerOf>
            <dap:Url>
                <xsl:attribute name="rdf:ID">
                    <xsl:call-template name="localIdWorker"/>
                </xsl:attribute>
                <xsl:apply-templates select="dap:Attribute" mode="body"/>
                <xsl:call-template name="localId"/>
            </dap:Url>
        </dapObj:isContainerOf>
    </xsl:template>
 
    <!-- ################################################################### -->
 
 
    <!-- ###################################################################
    -
    -    dapObj:localId
    -
    -
    -->
    <xsl:template name="localId">
        <dapObj:localId rdf:datatype="http://www.w3.org/2001/XMLSchema#string"><xsl:call-template name="localIdWorker"/></dapObj:localId>
    </xsl:template>
 
    <xsl:template match="*" name="localIdWorker" mode="localId">
        <xsl:if test="generate-id(.)!=generate-id(/dap:Dataset)">
            <xsl:apply-templates select=".." mode="localId"/>
            <xsl:if test="generate-id(..)!=generate-id(/dap:Dataset) and
                          not(parent::dap:Array) and
                          not(parent::dap:Map)">.</xsl:if><xsl:value-of select="@name"/></xsl:if>
    </xsl:template>
    <!-- ################################################################### -->
 
 
    <!-- ###################################################################
    -
    -
    -    Array Mode. ( mode="array" )
    -
    -
    -->
    <xsl:template match="*" mode="array"/>
 
    <xsl:template name="arrayDimension">
        <dapObj:hasDimensions rdf:parseType="Collection">
            <xsl:for-each select="../dap:dimension">
                <dap:dimension>
                    <dapObj:size>
                        <xsl:value-of select="@size"/>
                    </dapObj:size>
                    <xsl:if test="@name">
                        <dapObj:name>
                            <xsl:value-of select="@name"/>
                        </dapObj:name>
                    </xsl:if>
                </dap:dimension>
            </xsl:for-each>
        </dapObj:hasDimensions>
    </xsl:template>
 
 
    <!-- - - - - - - - - - - - - - - - - - -
    -
    - Template:    basicArrayTypeContents
    -
    - All Arrays have this set of stuff
    -
    -
    -->
    <xsl:template name="basicArrayTypeContents">
        <xsl:attribute name="rdf:ID">
            <xsl:call-template name="localIdWorker"/>
        </xsl:attribute>
 
        <!-- Since at this point the current node is the Array template,
      we need to look to the parent node (the Array) to get our Attribute
      elements. -->
        <xsl:apply-templates select="../dap:Attribute" mode="body"/>
 
        <!-- The template object should not have Attributes. We
    check for those anyway.... -->
        <xsl:apply-templates select="dap:Attribute" mode="body"/>
 
        <xsl:call-template name="arrayDimension"/>
        <xsl:call-template name="localId"/>
    </xsl:template>
 
 
    <xsl:template match="dap:Array" mode="array">
        <ERROR>Arrays of Arrays ar not permitted in the DAP. Since this XSL
            should be processing a legitimate DDX, this error should never occur.
            (rofl)
        </ERROR>
    </xsl:template>
 
 
    <xsl:template match="dap:Grid" mode="array">
        <dap:Grid>
            <xsl:call-template name="basicArrayTypeContents"/>
            <xsl:apply-templates select="dap:Array" mode="body"/>
            <xsl:apply-templates select="dap:Map" mode="body"/>
        </dap:Grid>
    </xsl:template>
 
    <xsl:template match="dap:Sequence" mode="array">
        <dap:Sequence>
            <xsl:call-template name="basicArrayTypeContents"/>
            <xsl:apply-templates mode="body"/>
        </dap:Sequence>
    </xsl:template>
 
    <xsl:template match="dap:Structure" mode="array">
        <dap:Structure>
            <xsl:call-template name="basicArrayTypeContents"/>
            <xsl:apply-templates mode="body"/>
        </dap:Structure>
    </xsl:template>
 
    <xsl:template match="dap:String" mode="array">
        <dap:String>
            <xsl:call-template name="basicArrayTypeContents"/>
        </dap:String>
    </xsl:template>
 
    <xsl:template match="dap:Url" mode="array">
        <dap:Url>
            <xsl:call-template name="basicArrayTypeContents"/>
        </dap:Url>
    </xsl:template>
 
    <xsl:template match="dap:Byte" mode="array">
        <dap:Byte>
            <xsl:call-template name="basicArrayTypeContents"/>
        </dap:Byte>
    </xsl:template>
 
    <xsl:template match="dap:Int16" mode="array">
        <dap:Int16>
            <xsl:call-template name="basicArrayTypeContents"/>
        </dap:Int16>
    </xsl:template>
 
    <xsl:template match="dap:UInt16" mode="array">
        <dap:UInt16>
            <xsl:call-template name="basicArrayTypeContents"/>
        </dap:UInt16>
    </xsl:template>
 
    <xsl:template match="dap:Int32" mode="array">
        <dap:Int32>
            <xsl:call-template name="basicArrayTypeContents"/>
        </dap:Int32>
    </xsl:template>
 
    <xsl:template match="dap:UInt32" mode="array">
        <dap:UInt32>
            <xsl:call-template name="basicArrayTypeContents"/>
        </dap:UInt32>
    </xsl:template>
 
    <xsl:template match="dap:Float32" mode="array">
        <dap:Float32>
            <xsl:call-template name="basicArrayTypeContents"/>
        </dap:Float32>
    </xsl:template>
 
    <xsl:template match="dap:Float64" mode="array">
        <dap:Float64>
            <xsl:call-template name="basicArrayTypeContents"/>
        </dap:Float64>
    </xsl:template>
 
    <!-- ################################################################### -->
 
 
    <!-- ###################################################################
      -
      -  Summary of Content
      -
    -->
    <xsl:template mode="summary"
                  match="dap:Attribute"/>
 
    <xsl:template mode="OFF"
                  match="dap:Attribute">
 
 
        <xsl:element name="{@name}">
 
            <xsl:if test="@type='Container'">
                <xsl:apply-templates mode="summary" select="dap:Attribute"/>
            </xsl:if>
 
            <xsl:if test="not(./Attribute)">
                <xsl:value-of select="dap:value"/>
            </xsl:if>
        </xsl:element>
    </xsl:template>
 
 
    <xsl:template mode="summary"
                  match="child::dap:value"/>
 
 
    <xsl:template mode="summary"
                  match="*[not(self::dap:Attribute)  and
                        not(parent::dap:Attribute)  and
                        not(self::dap:dataBLOB)]"
            >
        <!-- Applying mode Summary template to <xsl:copy /> -->
        <dapObj:isContainerOf rdf:resource="#{@name}"/>
 
    </xsl:template>
 
    <!-- ################################################################### -->
 
 
    <!-- ###################################################################
    -
    -
    -    Convert each Attribute to an RDF property. ( mode="AttPropDef" )
    -
    -
    -->
    <xsl:template name="AttPropDef">
 
 
        <xsl:for-each
                select="//dap:Attribute[generate-id() = generate-id(key('AttributeNames', @name))]">
            <owl:DatatypeProperty rdf:about="{$LocalAttributeNS}{@name}">
                <rdfs:domain
                        rdf:resource="&DAPOBJ;Container"/>
                <rdfs:isDefinedBy rdf:resource="{$LocalOntology}"/>
            </owl:DatatypeProperty>
        </xsl:for-each>
    </xsl:template>
 
 
</xsl:stylesheet>
 
</pre>
 
==== RDF Result ====
 
<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:dap="http://xml.opendap.org/ns/DAP/3.3#"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:cf="http://iridl.ldeo.columbia.edu/ontologies/cf-att.owl#"
        xmlns:dapObj="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#"
        xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
        xmlns:owl="http://www.w3.org/2002/07/owl#"
        xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
        xml:base="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx">
  <owl:Ontology rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf">
      <owl:imports rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl"/>
      <owl:imports rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/NetcdfConventionRegistry.owl"/>
  </owl:Ontology>
  <dapObj:Dataset rdf:about="">
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
      <dapObj:dataset_id rdf:datatype="http://www.w3.org/2001/XMLSchema#string"/>
      <rdf:type>
        <CoverageDescription xmlns="http://www.opengis.net/wcs/1.1" xmlns:ows="http://www.opengis.net/ows/1.1"
                              xmlns:owcs="http://www.opengis.net/wcs/1.1/ows"
                              xmlns:gml="http://www.opengis.net/gml/3.2"
                              xmlns:xlink="http://www.w3.org/1999/xlink"
                              xmlns:schemaLocation="http://www.opengis.net/wcs/1.1  http://schemas.opengis.net/wcs/1.1.0/wcsDescribeCoverage.xsd  http://www.opengis.net/ows/1.1  http://schemas.opengis.net/ows/1.1.0/owsAll.xsd  http://www.opengis.net/wcs/1.1/ows http://schemas.opengis.net/wcs/1.1.0/owsDataIdentification.xsd http://www.opengis.net/gml/3.2  http://schemas.opengis.net/gml/3.2.1/gml.xsd"
                              xmlns:grddl="http://www.w3.org/2003/g/data-view#">
            <ows:Title>Near-Real Time Surface Ocean Velocity</ows:Title>
            <ows:Abstract>CoverageDescription generated by OPeNDAP WCS UseCase 2.0</ows:Abstract>
            <Identifier>coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc</Identifier>
            <dapObj:xmlContains>
              <Domain>
                  <dapObj:xmlContains>
                    <SpatialDomain>
                        <dapObj:xmlContains>
                          <ows:BoundingBox>
                              <dapObj:xmlAttribute dapObj:name="crs" rdf:value="urn:ogc:def:crs:EPSG::4326"/>
                              <ows:LowerCorner>-97.8839 21.736</ows:LowerCorner>
                              <ows:UpperCorner>-57.2312 46.4944</ows:UpperCorner>
                          </ows:BoundingBox>
                        </dapObj:xmlContains>
                    </SpatialDomain>
                  </dapObj:xmlContains>
                  <dapObj:xmlContains>
                    <TemporalDomain>
                        <gml:timePosition>2008-03-27T16:00:00.000Z</gml:timePosition>
                    </TemporalDomain>
                  </dapObj:xmlContains>
              </Domain>
            </dapObj:xmlContains>
            <dapObj:xmlContains>
              <Range>
                  <dapObj:xmlContains>
                    <Field>
                        <ows:Title>surface_eastward_sea_water_velocity</ows:Title>
                        <ows:Abstract>Eastward component of a 2D sea surface velocity vector.</ows:Abstract>
                        <Identifier>u</Identifier>
                        <dapObj:xmlContains>
                          <Definition>
                              <ows:AnyValue/>
                          </Definition>
                        </dapObj:xmlContains>
                        <NullValue>-32768</NullValue>
                        <dapObj:xmlContains>
                          <owcs:InterpolationMethods>
                              <owcs:DefaultMethod>nearest</owcs:DefaultMethod>
                          </owcs:InterpolationMethods>
                        </dapObj:xmlContains>
                    </Field>
                  </dapObj:xmlContains>
                  <dapObj:xmlContains>
                    <Field>
                        <ows:Title>surface_northward_sea_water_velocity</ows:Title>
                        <ows:Abstract>Northward component of a 2D sea surface velocity vector.</ows:Abstract>
                        <Identifier>v</Identifier>
                        <dapObj:xmlContains>
                          <Definition>
                              <ows:AnyValue/>
                          </Definition>
                        </dapObj:xmlContains>
                        <NullValue>-32768</NullValue>
                        <dapObj:xmlContains>
                          <owcs:InterpolationMethods>
                              <owcs:DefaultMethod>nearest</owcs:DefaultMethod>
                          </owcs:InterpolationMethods>
                        </dapObj:xmlContains>
                    </Field>
                  </dapObj:xmlContains>
                  <dapObj:xmlContains>
                    <Field>
                        <ows:Title>longitudinal dilution of precision</ows:Title>
                        <ows:Abstract>The longitudinal dilution of precision (DOPx) represents the\\012contribution of the
                            radars' configuration geometry to\\012uncertainty in the eastward velocity estimate (u). DOPx
                            is a\\012direct multiplier of the standard error in obtaining the\\012standard deviation for the
                            eastward velocity estimate from the\\012least squares best fit. DOPx and DOPy are commonly used
                            to\\012obtain the geometric dilution of precision\\012(GDOP = sqrt(DOPx^2 + DOPy^2)), a useful
                            metric for filtering\\012errant velocities due to poor geometry.
                        </ows:Abstract>
                        <Identifier>DOPx</Identifier>
                        <dapObj:xmlContains>
                          <Definition>
                              <ows:AnyValue/>
                          </Definition>
                        </dapObj:xmlContains>
                        <NullValue>-32768</NullValue>
                        <dapObj:xmlContains>
                          <owcs:InterpolationMethods>
                              <owcs:DefaultMethod>nearest</owcs:DefaultMethod>
                          </owcs:InterpolationMethods>
                        </dapObj:xmlContains>
                    </Field>
                  </dapObj:xmlContains>
                  <dapObj:xmlContains>
                    <Field>
                        <ows:Title>latitudinal dilution of precision</ows:Title>
                        <ows:Abstract>The latitudinal dilution of precision (DOPy) represents the\\012contribution of the radars'
                            configuration geometry to\\012uncertainty in the northward velocity estimate (v). DOPy is
                            a\\012direct multiplier of the standard error in obtaining the\\012standard deviation for the
                            northward velocity estimate from the\\012least squares best fit. DOPx and DOPy are commonly used
                            to\\012obtain the geometric dilution of precision\\012(GDOP = sqrt(DOPx^2 + DOPy^2)), a useful
                            metric for filtering\\012errant velocities due to poor geometry.
                        </ows:Abstract>
                        <Identifier>DOPy</Identifier>
                        <dapObj:xmlContains>
                          <Definition>
                              <ows:AnyValue/>
                          </Definition>
                        </dapObj:xmlContains>
                        <NullValue>-32768</NullValue>
                        <dapObj:xmlContains>
                          <owcs:InterpolationMethods>
                              <owcs:DefaultMethod>nearest</owcs:DefaultMethod>
                          </owcs:InterpolationMethods>
                        </dapObj:xmlContains>
                    </Field>
                  </dapObj:xmlContains>
              </Range>
            </dapObj:xmlContains>
            <SupportedCRS>urn:ogc:def:crs:EPSG::4326</SupportedCRS>
            <SupportedFormat>netcdf-cf1.0</SupportedFormat>
            <SupportedFormat>dap2.0</SupportedFormat>
        </CoverageDescription>
      </rdf:type>
      <att:site_code xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                    rdf:parseType="Resource">
        <att:long_name rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Contributing radar site code</att:long_name>
      </att:site_code>
      <att:site_netCode xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                        rdf:parseType="Resource">
        <att:long_name rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Contributing radar site network affiliation code</att:long_name>
      </att:site_netCode>
      <att:NC_GLOBAL xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                    rdf:parseType="Resource">
        <att:netcdf_library_version rdf:datatype="http://www.w3.org/2001/XMLSchema#string">netcdf library version 3.6.1 of Feb 3 2008 23:15:25 $</att:netcdf_library_version>
        <att:format_version rdf:datatype="http://www.w3.org/2001/XMLSchema#string">HFRNet_1.0.0b2</att:format_version>
        <att:product_version rdf:datatype="http://www.w3.org/2001/XMLSchema#string">HFRNet_1.1.01</att:product_version>
        <att:Conventions rdf:datatype="http://www.w3.org/2001/XMLSchema#string">CF-1.1</att:Conventions>
        <att:title rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Near-Real Time Surface Ocean Velocity</att:title>
        <att:institution rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Scripps Institution of Oceanography</att:institution>
        <att:source rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Surface Ocean HF-Radar</att:source>
        <att:history rdf:datatype="http://www.w3.org/2001/XMLSchema#string">12-Mar-2008 22:26:19: NetCDF file created</att:history>
        <att:references rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Terrill, E. et al., 2006. Data Management and Real-time\\012Distribution in the HF-Radar National
                Network. Proceedings\\012of the MTS/IEEE Oceans 2006 Conference, Boston MA,\\012September 2006.
            </att:references>
        <att:creator_name rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Mark Otero</att:creator_name>
        <att:creator_email rdf:datatype="http://www.w3.org/2001/XMLSchema#string">motero@mpl.ucsd.edu</att:creator_email>
        <att:creator_url rdf:datatype="http://www.w3.org/2001/XMLSchema#string">http://cordc.ucsd.edu/projects/mapping/</att:creator_url>
        <att:summary rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Surface ocean velocities estimated from HF-Radar are\\012representitive of the upper 0.3 - 2.5 meters
                of the\\012ocean. The main objective of near-real time\\012processing is to produce the best product
                from\\012available data at the time of processing. Radial\\012velocity measurements are obtained from
                individual\\012radar sites through the HF-Radar Network and\\012processed to create near-real time
                velocities\\012(RTVs)
            </att:summary>
        <att:geospatial_lat_min rdf:datatype="http://www.w3.org/2001/XMLSchema#float">21.73596001</att:geospatial_lat_min>
        <att:geospatial_lat_max rdf:datatype="http://www.w3.org/2001/XMLSchema#float">46.49441910</att:geospatial_lat_max>
        <att:geospatial_lon_min rdf:datatype="http://www.w3.org/2001/XMLSchema#float">-97.88385010</att:geospatial_lon_min>
        <att:geospatial_lon_max rdf:datatype="http://www.w3.org/2001/XMLSchema#float">-57.23120880</att:geospatial_lon_max>
        <att:grid_resolution rdf:datatype="http://www.w3.org/2001/XMLSchema#string">6km</att:grid_resolution>
        <att:grid_projection rdf:datatype="http://www.w3.org/2001/XMLSchema#string">equidistant cylindrical</att:grid_projection>
        <att:regional_description rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Unites States, East and Gulf Coast</att:regional_description>
      </att:NC_GLOBAL>
      <att:DODS_EXTRA xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                      rdf:parseType="Resource">
        <att:Unlimited_Dimension rdf:datatype="http://www.w3.org/2001/XMLSchema#string">time</att:Unlimited_Dimension>
      </att:DODS_EXTRA>
      <dapObj:isContainerOf>
        <dap:Int32 rdf:ID="time">
            <att:standard_name xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                              rdf:datatype="http://www.w3.org/2001/XMLSchema#string">time</att:standard_name>
            <att:units xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                      rdf:datatype="http://www.w3.org/2001/XMLSchema#string">seconds since 1970-01-01</att:units>
            <att:calendar xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                          rdf:datatype="http://www.w3.org/2001/XMLSchema#string">gregorian</att:calendar>
            <dapObj:hasDimensions rdf:parseType="Collection">
              <dap:dimension>
                  <dapObj:size>1</dapObj:size>
                  <dapObj:name>time</dapObj:name>
              </dap:dimension>
            </dapObj:hasDimensions>
            <dapObj:localId rdf:datatype="http://www.w3.org/2001/XMLSchema#string">time</dapObj:localId>
        </dap:Int32>
      </dapObj:isContainerOf>
      <dapObj:isContainerOf>
        <dap:Float32 rdf:ID="lat">
            <att:standard_name xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                              rdf:datatype="http://www.w3.org/2001/XMLSchema#string">latitude</att:standard_name>
            <att:units xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                      rdf:datatype="http://www.w3.org/2001/XMLSchema#string">degrees_north</att:units>
            <dapObj:hasDimensions rdf:parseType="Collection">
              <dap:dimension>
                  <dapObj:size>460</dapObj:size>
                  <dapObj:name>lat</dapObj:name>
              </dap:dimension>
            </dapObj:hasDimensions>
            <dapObj:localId rdf:datatype="http://www.w3.org/2001/XMLSchema#string">lat</dapObj:localId>
        </dap:Float32>
      </dapObj:isContainerOf>
      <dapObj:isContainerOf>
        <dap:Float32 rdf:ID="lon">
            <att:standard_name xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                              rdf:datatype="http://www.w3.org/2001/XMLSchema#string">longitude</att:standard_name>
            <att:units xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                      rdf:datatype="http://www.w3.org/2001/XMLSchema#string">degrees_east</att:units>
            <dapObj:hasDimensions rdf:parseType="Collection">
              <dap:dimension>
                  <dapObj:size>701</dapObj:size>
                  <dapObj:name>lon</dapObj:name>
              </dap:dimension>
            </dapObj:hasDimensions>
            <dapObj:localId rdf:datatype="http://www.w3.org/2001/XMLSchema#string">lon</dapObj:localId>
        </dap:Float32>
      </dapObj:isContainerOf>
      <dapObj:isContainerOf>
        <dap:Grid rdf:ID="u">
            <att:standard_name xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                              rdf:datatype="http://www.w3.org/2001/XMLSchema#string">surface_eastward_sea_water_velocity</att:standard_name>
            <att:units xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                      rdf:datatype="http://www.w3.org/2001/XMLSchema#string">m s-1</att:units>
            <att:_FillValue xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                            rdf:datatype="http://www.w3.org/2001/XMLSchema#short">-32768</att:_FillValue>
            <att:scale_factor xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                              rdf:datatype="http://www.w3.org/2001/XMLSchema#float">0.009999999776</att:scale_factor>
            <att:ancillary_variables xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                                    rdf:datatype="http://www.w3.org/2001/XMLSchema#string">DOPx</att:ancillary_variables>
            <dapObj:isContainerOf>
              <dap:Int16 rdf:ID="u.u">
                  <dapObj:hasDimensions rdf:parseType="Collection">
                    <dap:dimension>
                        <dapObj:size>1</dapObj:size>
                        <dapObj:name>time</dapObj:name>
                    </dap:dimension>
                    <dap:dimension>
                        <dapObj:size>460</dapObj:size>
                        <dapObj:name>lat</dapObj:name>
                    </dap:dimension>
                    <dap:dimension>
                        <dapObj:size>701</dapObj:size>
                        <dapObj:name>lon</dapObj:name>
                    </dap:dimension>
                  </dapObj:hasDimensions>
                  <dapObj:localId rdf:datatype="http://www.w3.org/2001/XMLSchema#string">u.u</dapObj:localId>
              </dap:Int16>
            </dapObj:isContainerOf>
            <dapObj:hasMap>
              <dap:Int32 rdf:ID="u.time">
                  <dapObj:hasDimensions rdf:parseType="Collection">
                    <dap:dimension>
                        <dapObj:size>1</dapObj:size>
                        <dapObj:name>time</dapObj:name>
                    </dap:dimension>
                  </dapObj:hasDimensions>
                  <dapObj:localId rdf:datatype="http://www.w3.org/2001/XMLSchema#string">u.time</dapObj:localId>
              </dap:Int32>
            </dapObj:hasMap>
            <dapObj:hasMap>
              <dap:Float32 rdf:ID="u.lat">
                  <dapObj:hasDimensions rdf:parseType="Collection">
                    <dap:dimension>
                        <dapObj:size>460</dapObj:size>
                        <dapObj:name>lat</dapObj:name>
                    </dap:dimension>
                  </dapObj:hasDimensions>
                  <dapObj:localId rdf:datatype="http://www.w3.org/2001/XMLSchema#string">u.lat</dapObj:localId>
              </dap:Float32>
            </dapObj:hasMap>
            <dapObj:hasMap>
              <dap:Float32 rdf:ID="u.lon">
                  <dapObj:hasDimensions rdf:parseType="Collection">
                    <dap:dimension>
                        <dapObj:size>701</dapObj:size>
                        <dapObj:name>lon</dapObj:name>
                    </dap:dimension>
                  </dapObj:hasDimensions>
                  <dapObj:localId rdf:datatype="http://www.w3.org/2001/XMLSchema#string">u.lon</dapObj:localId>
              </dap:Float32>
            </dapObj:hasMap>
            <dapObj:localId rdf:datatype="http://www.w3.org/2001/XMLSchema#string">u</dapObj:localId>
        </dap:Grid>
      </dapObj:isContainerOf>
      <dapObj:isContainerOf>
        <dap:Grid rdf:ID="v">
            <att:standard_name xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                              rdf:datatype="http://www.w3.org/2001/XMLSchema#string">surface_northward_sea_water_velocity</att:standard_name>
            <att:units xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                      rdf:datatype="http://www.w3.org/2001/XMLSchema#string">m s-1</att:units>
            <att:_FillValue xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                            rdf:datatype="http://www.w3.org/2001/XMLSchema#short">-32768</att:_FillValue>
            <att:scale_factor xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                              rdf:datatype="http://www.w3.org/2001/XMLSchema#float">0.009999999776</att:scale_factor>
            <att:ancillary_variables xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                                    rdf:datatype="http://www.w3.org/2001/XMLSchema#string">DOPy</att:ancillary_variables>
            <dapObj:isContainerOf>
              <dap:Int16 rdf:ID="v.v">
                  <dapObj:hasDimensions rdf:parseType="Collection">
                    <dap:dimension>
                        <dapObj:size>1</dapObj:size>
                        <dapObj:name>time</dapObj:name>
                    </dap:dimension>
                    <dap:dimension>
                        <dapObj:size>460</dapObj:size>
                        <dapObj:name>lat</dapObj:name>
                    </dap:dimension>
                    <dap:dimension>
                        <dapObj:size>701</dapObj:size>
                        <dapObj:name>lon</dapObj:name>
                    </dap:dimension>
                  </dapObj:hasDimensions>
                  <dapObj:localId rdf:datatype="http://www.w3.org/2001/XMLSchema#string">v.v</dapObj:localId>
              </dap:Int16>
            </dapObj:isContainerOf>
            <dapObj:hasMap>
              <dap:Int32 rdf:ID="v.time">
                  <dapObj:hasDimensions rdf:parseType="Collection">
                    <dap:dimension>
                        <dapObj:size>1</dapObj:size>
                        <dapObj:name>time</dapObj:name>
                    </dap:dimension>
                  </dapObj:hasDimensions>
                  <dapObj:localId rdf:datatype="http://www.w3.org/2001/XMLSchema#string">v.time</dapObj:localId>
              </dap:Int32>
            </dapObj:hasMap>
            <dapObj:hasMap>
              <dap:Float32 rdf:ID="v.lat">
                  <dapObj:hasDimensions rdf:parseType="Collection">
                    <dap:dimension>
                        <dapObj:size>460</dapObj:size>
                        <dapObj:name>lat</dapObj:name>
                    </dap:dimension>
                  </dapObj:hasDimensions>
                  <dapObj:localId rdf:datatype="http://www.w3.org/2001/XMLSchema#string">v.lat</dapObj:localId>
              </dap:Float32>
            </dapObj:hasMap>
            <dapObj:hasMap>
              <dap:Float32 rdf:ID="v.lon">
                  <dapObj:hasDimensions rdf:parseType="Collection">
                    <dap:dimension>
                        <dapObj:size>701</dapObj:size>
                        <dapObj:name>lon</dapObj:name>
                    </dap:dimension>
                  </dapObj:hasDimensions>
                  <dapObj:localId rdf:datatype="http://www.w3.org/2001/XMLSchema#string">v.lon</dapObj:localId>
              </dap:Float32>
            </dapObj:hasMap>
            <dapObj:localId rdf:datatype="http://www.w3.org/2001/XMLSchema#string">v</dapObj:localId>
        </dap:Grid>
      </dapObj:isContainerOf>
      <dapObj:isContainerOf>
        <dap:Grid rdf:ID="DOPx">
            <att:long_name xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                          rdf:datatype="http://www.w3.org/2001/XMLSchema#string">longitudinal dilution of precision</att:long_name>
            <att:comment xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                        rdf:datatype="http://www.w3.org/2001/XMLSchema#string">The longitudinal dilution of precision (DOPx) represents the\\012contribution of the radars'
                configuration geometry to\\012uncertainty in the eastward velocity estimate (u). DOPx is a\\012direct
                multiplier of the standard error in obtaining the\\012standard deviation for the eastward velocity
                estimate from the\\012least squares best fit. DOPx and DOPy are commonly used to\\012obtain the
                geometric dilution of precision\\012(GDOP = sqrt(DOPx^2 + DOPy^2)), a useful metric for
                filtering\\012errant velocities due to poor geometry.
            </att:comment>
            <att:_FillValue xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                            rdf:datatype="http://www.w3.org/2001/XMLSchema#short">-32768</att:_FillValue>
            <att:scale_factor xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                              rdf:datatype="http://www.w3.org/2001/XMLSchema#float">0.009999999776</att:scale_factor>
            <dapObj:isContainerOf>
              <dap:Int16 rdf:ID="DOPx.DOPx">
                  <dapObj:hasDimensions rdf:parseType="Collection">
                    <dap:dimension>
                        <dapObj:size>1</dapObj:size>
                        <dapObj:name>time</dapObj:name>
                    </dap:dimension>
                    <dap:dimension>
                        <dapObj:size>460</dapObj:size>
                        <dapObj:name>lat</dapObj:name>
                    </dap:dimension>
                    <dap:dimension>
                        <dapObj:size>701</dapObj:size>
                        <dapObj:name>lon</dapObj:name>
                    </dap:dimension>
                  </dapObj:hasDimensions>
                  <dapObj:localId rdf:datatype="http://www.w3.org/2001/XMLSchema#string">DOPx.DOPx</dapObj:localId>
              </dap:Int16>
            </dapObj:isContainerOf>
            <dapObj:hasMap>
              <dap:Int32 rdf:ID="DOPx.time">
                  <dapObj:hasDimensions rdf:parseType="Collection">
                    <dap:dimension>
                        <dapObj:size>1</dapObj:size>
                        <dapObj:name>time</dapObj:name>
                    </dap:dimension>
                  </dapObj:hasDimensions>
                  <dapObj:localId rdf:datatype="http://www.w3.org/2001/XMLSchema#string">DOPx.time</dapObj:localId>
              </dap:Int32>
            </dapObj:hasMap>
            <dapObj:hasMap>
              <dap:Float32 rdf:ID="DOPx.lat">
                  <dapObj:hasDimensions rdf:parseType="Collection">
                    <dap:dimension>
                        <dapObj:size>460</dapObj:size>
                        <dapObj:name>lat</dapObj:name>
                    </dap:dimension>
                  </dapObj:hasDimensions>
                  <dapObj:localId rdf:datatype="http://www.w3.org/2001/XMLSchema#string">DOPx.lat</dapObj:localId>
              </dap:Float32>
            </dapObj:hasMap>
            <dapObj:hasMap>
              <dap:Float32 rdf:ID="DOPx.lon">
                  <dapObj:hasDimensions rdf:parseType="Collection">
                    <dap:dimension>
                        <dapObj:size>701</dapObj:size>
                        <dapObj:name>lon</dapObj:name>
                    </dap:dimension>
                  </dapObj:hasDimensions>
                  <dapObj:localId rdf:datatype="http://www.w3.org/2001/XMLSchema#string">DOPx.lon</dapObj:localId>
              </dap:Float32>
            </dapObj:hasMap>
            <dapObj:localId rdf:datatype="http://www.w3.org/2001/XMLSchema#string">DOPx</dapObj:localId>
        </dap:Grid>
      </dapObj:isContainerOf>
      <dapObj:isContainerOf>
        <dap:Grid rdf:ID="DOPy">
            <att:long_name xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                          rdf:datatype="http://www.w3.org/2001/XMLSchema#string">latitudinal dilution of precision</att:long_name>
            <att:comment xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                        rdf:datatype="http://www.w3.org/2001/XMLSchema#string">The latitudinal dilution of precision (DOPy) represents the\\012contribution of the radars'
                configuration geometry to\\012uncertainty in the northward velocity estimate (v). DOPy is a\\012direct
                multiplier of the standard error in obtaining the\\012standard deviation for the northward velocity
                estimate from the\\012least squares best fit. DOPx and DOPy are commonly used to\\012obtain the
                geometric dilution of precision\\012(GDOP = sqrt(DOPx^2 + DOPy^2)), a useful metric for
                filtering\\012errant velocities due to poor geometry.
            </att:comment>
            <att:_FillValue xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                            rdf:datatype="http://www.w3.org/2001/XMLSchema#short">-32768</att:_FillValue>
            <att:scale_factor xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                              rdf:datatype="http://www.w3.org/2001/XMLSchema#float">0.009999999776</att:scale_factor>
            <dapObj:isContainerOf>
              <dap:Int16 rdf:ID="DOPy.DOPy">
                  <dapObj:hasDimensions rdf:parseType="Collection">
                    <dap:dimension>
                        <dapObj:size>1</dapObj:size>
                        <dapObj:name>time</dapObj:name>
                    </dap:dimension>
                    <dap:dimension>
                        <dapObj:size>460</dapObj:size>
                        <dapObj:name>lat</dapObj:name>
                    </dap:dimension>
                    <dap:dimension>
                        <dapObj:size>701</dapObj:size>
                        <dapObj:name>lon</dapObj:name>
                    </dap:dimension>
                  </dapObj:hasDimensions>
                  <dapObj:localId rdf:datatype="http://www.w3.org/2001/XMLSchema#string">DOPy.DOPy</dapObj:localId>
              </dap:Int16>
            </dapObj:isContainerOf>
            <dapObj:hasMap>
              <dap:Int32 rdf:ID="DOPy.time">
                  <dapObj:hasDimensions rdf:parseType="Collection">
                    <dap:dimension>
                        <dapObj:size>1</dapObj:size>
                        <dapObj:name>time</dapObj:name>
                    </dap:dimension>
                  </dapObj:hasDimensions>
                  <dapObj:localId rdf:datatype="http://www.w3.org/2001/XMLSchema#string">DOPy.time</dapObj:localId>
              </dap:Int32>
            </dapObj:hasMap>
            <dapObj:hasMap>
              <dap:Float32 rdf:ID="DOPy.lat">
                  <dapObj:hasDimensions rdf:parseType="Collection">
                    <dap:dimension>
                        <dapObj:size>460</dapObj:size>
                        <dapObj:name>lat</dapObj:name>
                    </dap:dimension>
                  </dapObj:hasDimensions>
                  <dapObj:localId rdf:datatype="http://www.w3.org/2001/XMLSchema#string">DOPy.lat</dapObj:localId>
              </dap:Float32>
            </dapObj:hasMap>
            <dapObj:hasMap>
              <dap:Float32 rdf:ID="DOPy.lon">
                  <dapObj:hasDimensions rdf:parseType="Collection">
                    <dap:dimension>
                        <dapObj:size>701</dapObj:size>
                        <dapObj:name>lon</dapObj:name>
                    </dap:dimension>
                  </dapObj:hasDimensions>
                  <dapObj:localId rdf:datatype="http://www.w3.org/2001/XMLSchema#string">DOPy.lon</dapObj:localId>
              </dap:Float32>
            </dapObj:hasMap>
            <dapObj:localId rdf:datatype="http://www.w3.org/2001/XMLSchema#string">DOPy</dapObj:localId>
        </dap:Grid>
      </dapObj:isContainerOf>
      <dapObj:isContainerOf>
        <dap:Float32 rdf:ID="site_lat">
            <att:long_name xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                          rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Contributing radar site latitudes</att:long_name>
            <att:standard_name xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                              rdf:datatype="http://www.w3.org/2001/XMLSchema#string">latitude</att:standard_name>
            <att:units xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                      rdf:datatype="http://www.w3.org/2001/XMLSchema#string">degrees_north</att:units>
            <dapObj:hasDimensions rdf:parseType="Collection">
              <dap:dimension>
                  <dapObj:size>27</dapObj:size>
                  <dapObj:name>nSites</dapObj:name>
              </dap:dimension>
            </dapObj:hasDimensions>
            <dapObj:localId rdf:datatype="http://www.w3.org/2001/XMLSchema#string">site_lat</dapObj:localId>
        </dap:Float32>
      </dapObj:isContainerOf>
      <dapObj:isContainerOf>
        <dap:Float32 rdf:ID="site_lon">
            <att:long_name xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                          rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Contributing radar site longitudes</att:long_name>
            <att:standard_name xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                              rdf:datatype="http://www.w3.org/2001/XMLSchema#string">longitude</att:standard_name>
            <att:units xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                      rdf:datatype="http://www.w3.org/2001/XMLSchema#string">degrees_east</att:units>
            <dapObj:hasDimensions rdf:parseType="Collection">
              <dap:dimension>
                  <dapObj:size>27</dapObj:size>
                  <dapObj:name>nSites</dapObj:name>
              </dap:dimension>
            </dapObj:hasDimensions>
            <dapObj:localId rdf:datatype="http://www.w3.org/2001/XMLSchema#string">site_lon</dapObj:localId>
        </dap:Float32>
      </dapObj:isContainerOf>
      <dapObj:isContainerOf>
        <dap:Float32 rdf:ID="procParams">
            <att:long_name xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                          rdf:datatype="http://www.w3.org/2001/XMLSchema#string">RTV processing parameters</att:long_name>
            <att:comment xmlns:att="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#"
                        rdf:datatype="http://www.w3.org/2001/XMLSchema#string">\\01201) Maximum GDOP threshold\\01202) Maximum speed threshold (cm s-1)\\01203) Minimum number of
                sites required\\01204) Minimum number of radials required\\01205) Maximum angular gap to interpolate
                radial\\012 data over (degrees, 0 = no interpolation)\\01206) Maximum gap in range to interpolate
                radial\\012 data over (range-resolution, 0 = no interpolation)\\01207) Spatial search radius for radial
                solutions (km)
            </att:comment>
            <dapObj:hasDimensions rdf:parseType="Collection">
              <dap:dimension>
                  <dapObj:size>7</dapObj:size>
                  <dapObj:name>nProcParam</dapObj:name>
              </dap:dimension>
            </dapObj:hasDimensions>
            <dapObj:localId rdf:datatype="http://www.w3.org/2001/XMLSchema#string">procParams</dapObj:localId>
        </dap:Float32>
      </dapObj:isContainerOf>
  </dapObj:Dataset>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#wcsStuff">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#site_code">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#long_name">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#site_netCode">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#NC_GLOBAL">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#netcdf_library_version">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#format_version">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#product_version">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#Conventions">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#title">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#institution">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#source">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#history">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#references">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#creator_name">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#creator_email">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#creator_url">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#summary">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#geospatial_lat_min">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#geospatial_lat_max">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#geospatial_lon_min">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#geospatial_lon_max">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#grid_resolution">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#grid_projection">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#regional_description">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#DODS_EXTRA">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#Unlimited_Dimension">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#standard_name">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#units">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#calendar">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#_FillValue">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#scale_factor">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#ancillary_variables">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
  <owl:DatatypeProperty rdf:about="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx/att#comment">
      <rdfs:domain rdf:resource="http://iridl.ldeo.columbia.edu/ontologies/opendap.owl#Container"/>
      <rdfs:isDefinedBy rdf:resource="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx.rdf"/>
  </owl:DatatypeProperty>
</rdf:RDF>
 
=== Example 2 ===
 
In which missing components for WCS are added throughout the DDX as other XML.
 
====Source XML ====
<pre>
<?xml version="1.0" encoding="UTF-8"?>
<Dataset name="200803061600_HFRadar_USEGC_6km_rtv_SIO.nc"
        xmlns:grddl="http://www.w3.org/2003/g/data-view#"
        grddl:transformation="http://xml.opendap.org/transforms/ddxToRdfTriples.xsl"
        xmlns="http://xml.opendap.org/ns/DAP/3.3#"
        xmlns:dap="http://xml.opendap.org/ns/DAP/3.3#"
        dap_version="3.2"
        xmlns:xml="http://www.w3.org/XML/1998/namespace"
        xml:base="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx" >
 
    <Attribute name="nameNotUsed01" type="OtherXML" relationship="has-a" >
            <Domain xmlns="http://www.opengis.net/wcs/1.1"
                    xmlns:ows="http://www.opengis.net/ows/1.1"
                    xmlns:gml="http://www.opengis.net/gml/3.2"
                    >
                   
                    <SpatialDomain>
                        <ows:BoundingBox crs="urn:ogc:def:crs:EPSG::4326">
                            <ows:LowerCorner>-97.8839 21.736</ows:LowerCorner>
                            <ows:UpperCorner>-57.2312 46.4944</ows:UpperCorner>
                        </ows:BoundingBox>
                    </SpatialDomain>
                    <TemporalDomain>
                        <gml:timePosition>2008-03-27T16:00:00.000Z</gml:timePosition>
                    </TemporalDomain>
                </Domain>
               
                <SupportedCRS xmlns="http://www.opengis.net/wcs/1.1">urn:ogc:def:crs:EPSG::4326</SupportedCRS>
                <SupportedFormat xmlns="http://www.opengis.net/wcs/1.1">netcdf-cf1.0</SupportedFormat>
                <SupportedFormat xmlns="http://www.opengis.net/wcs/1.1">dap2.0</SupportedFormat>
    </Attribute>
 
 
   
    <Attribute name="site_code" type="Container">
        <Attribute name="long_name" type="String">
            <value>Contributing radar site code</value>
        </Attribute>
    </Attribute>
    <Attribute name="site_netCode" type="Container">
        <Attribute name="long_name" type="String">
            <value>Contributing radar site network affiliation code</value>
        </Attribute>
    </Attribute>
    <Attribute name="NC_GLOBAL" type="Container">
        <Attribute name="netcdf_library_version" type="String">
            <value>netcdf library version 3.6.1 of Feb 3 2008 23:15:25 $</value>
        </Attribute>
        <Attribute name="format_version" type="String">
            <value>HFRNet_1.0.0b2</value>
        </Attribute>
        <Attribute name="product_version" type="String">
            <value>HFRNet_1.1.01</value>
        </Attribute>
        <Attribute name="Conventions" type="String">
            <value>CF-1.1</value>
        </Attribute>
        <Attribute name="title" type="String">
            <value>Near-Real Time Surface Ocean Velocity</value>
        </Attribute>
        <Attribute name="institution" type="String">
            <value>Scripps Institution of Oceanography</value>
        </Attribute>
        <Attribute name="source" type="String">
            <value>Surface Ocean HF-Radar</value>
        </Attribute>
        <Attribute name="history" type="String">
            <value>12-Mar-2008 22:26:19: NetCDF file created</value>
        </Attribute>
        <Attribute name="references" type="String">
            <value>Terrill, E. et al., 2006. Data Management and Real-time\\012Distribution in the HF-Radar National
                Network. Proceedings\\012of the MTS/IEEE Oceans 2006 Conference, Boston MA,\\012September 2006.
            </value>
        </Attribute>
        <Attribute name="creator_name" type="String">
            <value>Mark Otero</value>
        </Attribute>
        <Attribute name="creator_email" type="String">
            <value>motero@mpl.ucsd.edu</value>
        </Attribute>
        <Attribute name="creator_url" type="String">
            <value>http://cordc.ucsd.edu/projects/mapping/</value>
        </Attribute>
        <Attribute name="summary" type="String">
            <value>Surface ocean velocities estimated from HF-Radar are\\012representitive of the upper 0.3 - 2.5 meters
                of the\\012ocean. The main objective of near-real time\\012processing is to produce the best product
                from\\012available data at the time of processing. Radial\\012velocity measurements are obtained from
                individual\\012radar sites through the HF-Radar Network and\\012processed to create near-real time
                velocities\\012(RTVs)
            </value>
        </Attribute>
        <Attribute name="geospatial_lat_min" type="Float32">
            <value>21.73596001</value>
        </Attribute>
        <Attribute name="geospatial_lat_max" type="Float32">
            <value>46.49441910</value>
        </Attribute>
        <Attribute name="geospatial_lon_min" type="Float32">
            <value>-97.88385010</value>
        </Attribute>
        <Attribute name="geospatial_lon_max" type="Float32">
            <value>-57.23120880</value>
        </Attribute>
        <Attribute name="grid_resolution" type="String">
            <value>6km</value>
        </Attribute>
        <Attribute name="grid_projection" type="String">
            <value>equidistant cylindrical</value>
        </Attribute>
        <Attribute name="regional_description" type="String">
            <value>Unites States, East and Gulf Coast</value>
        </Attribute>
    </Attribute>
    <Attribute name="DODS_EXTRA" type="Container">
        <Attribute name="Unlimited_Dimension" type="String">
            <value>time</value>
        </Attribute>
    </Attribute>
 
    <Array name="time">
        <Attribute name="standard_name" type="String">
            <value>time</value>
        </Attribute>
        <Attribute name="units" type="String">
            <value>seconds since 1970-01-01</value>
        </Attribute>
        <Attribute name="calendar" type="String">
            <value>gregorian</value>
        </Attribute>
        <Int32/>
        <dimension name="time" size="1"/>
    </Array>
    <Array name="lat">
        <Attribute name="standard_name" type="String">
            <value>latitude</value>
        </Attribute>
        <Attribute name="units" type="String">
            <value>degrees_north</value>
        </Attribute>
        <Float32/>
        <dimension name="lat" size="460"/>
    </Array>
    <Array name="lon">
        <Attribute name="standard_name" type="String">
            <value>longitude</value>
        </Attribute>
        <Attribute name="units" type="String">
            <value>degrees_east</value>
        </Attribute>
        <Float32/>
        <dimension name="lon" size="701"/>
    </Array>
 
    <Grid name="u">
        <Attribute name="nameNotUsed" type="OtherXML">
            <ows:Abstract xmlns:ows="http://www.opengis.net/ows/1.1">Eastward component of a 2D sea surface velocity vector.</ows:Abstract>
            <Definition xmlns="http://www.opengis.net/wcs/1.1"
                    xmlns:ows="http://www.opengis.net/ows/1.1"
                    >
                <ows:AnyValue/>
            </Definition>
            <owcs:InterpolationMethods xmlns:owcs="http://www.opengis.net/wcs/1.1/ows" >
                <owcs:DefaultMethod>nearest</owcs:DefaultMethod>
            </owcs:InterpolationMethods>
        </Attribute>
        <Attribute name="standard_name" type="String">
            <value>surface_eastward_sea_water_velocity</value>
        </Attribute>
        <Attribute name="units" type="String">
            <value>m s-1</value>
        </Attribute>
        <Attribute name="_FillValue" type="Int16">
            <value>-32768</value>
        </Attribute>
        <Attribute name="scale_factor" type="Float32">
            <value>0.009999999776</value>
        </Attribute>
        <Attribute name="ancillary_variables" type="String">
            <value>DOPx</value>
        </Attribute>
        <Array name="u">
            <Int16/>
            <dimension name="time" size="1"/>
            <dimension name="lat" size="460"/>
            <dimension name="lon" size="701"/>
        </Array>
        <Map name="time">
            <Int32/>
            <dimension name="time" size="1"/>
        </Map>
        <Map name="lat">
            <Float32/>
            <dimension name="lat" size="460"/>
        </Map>
        <Map name="lon">
            <Float32/>
            <dimension name="lon" size="701"/>
        </Map>
    </Grid>
    <Grid name="v">
        <Attribute name="nameNotUsed" type="OtherXML">
            <ows:Abstract xmlns:ows="http://www.opengis.net/ows/1.1">Northward component of a 2D sea surface velocity vector.</ows:Abstract>
            <Definition xmlns="http://www.opengis.net/wcs/1.1"
                    xmlns:ows="http://www.opengis.net/ows/1.1"
                    >
                <ows:AnyValue/>
            </Definition>
            <owcs:InterpolationMethods xmlns:owcs="http://www.opengis.net/wcs/1.1/ows" >
                <owcs:DefaultMethod>nearest</owcs:DefaultMethod>
            </owcs:InterpolationMethods>
        </Attribute>
        <Attribute name="standard_name" type="String">
            <value>surface_northward_sea_water_velocity</value>
        </Attribute>
        <Attribute name="units" type="String">
            <value>m s-1</value>
        </Attribute>
        <Attribute name="_FillValue" type="Int16">
            <value>-32768</value>
        </Attribute>
        <Attribute name="scale_factor" type="Float32">
            <value>0.009999999776</value>
        </Attribute>
        <Attribute name="ancillary_variables" type="String">
            <value>DOPy</value>
        </Attribute>
        <Array name="v">
            <Int16/>
            <dimension name="time" size="1"/>
            <dimension name="lat" size="460"/>
            <dimension name="lon" size="701"/>
        </Array>
        <Map name="time">
            <Int32/>
            <dimension name="time" size="1"/>
        </Map>
        <Map name="lat">
            <Float32/>
            <dimension name="lat" size="460"/>
        </Map>
        <Map name="lon">
            <Float32/>
            <dimension name="lon" size="701"/>
        </Map>
    </Grid>
    <Grid name="DOPx">
        <Attribute name="nameNotUsed" type="OtherXML">
            <Definition xmlns="http://www.opengis.net/wcs/1.1"
                    xmlns:ows="http://www.opengis.net/ows/1.1"
                    >
                <ows:AnyValue/>
            </Definition>
            <owcs:InterpolationMethods xmlns:owcs="http://www.opengis.net/wcs/1.1/ows" >
                <owcs:DefaultMethod>nearest</owcs:DefaultMethod>
            </owcs:InterpolationMethods>
        </Attribute>
        <Attribute name="long_name" type="String">
            <value>longitudinal dilution of precision</value>
        </Attribute>
        <Attribute name="comment" type="String">
            <value>The longitudinal dilution of precision (DOPx) represents the\\012contribution of the radars&apos;
                configuration geometry to\\012uncertainty in the eastward velocity estimate (u). DOPx is a\\012direct
                multiplier of the standard error in obtaining the\\012standard deviation for the eastward velocity
                estimate from the\\012least squares best fit. DOPx and DOPy are commonly used to\\012obtain the
                geometric dilution of precision\\012(GDOP = sqrt(DOPx^2 + DOPy^2)), a useful metric for
                filtering\\012errant velocities due to poor geometry.
            </value>
        </Attribute>
        <Attribute name="_FillValue" type="Int16">
            <value>-32768</value>
        </Attribute>
        <Attribute name="scale_factor" type="Float32">
            <value>0.009999999776</value>
        </Attribute>
        <Array name="DOPx">
            <Int16/>
            <dimension name="time" size="1"/>
            <dimension name="lat" size="460"/>
            <dimension name="lon" size="701"/>
        </Array>
        <Map name="time">
            <Int32/>
            <dimension name="time" size="1"/>
        </Map>
        <Map name="lat">
            <Float32/>
            <dimension name="lat" size="460"/>
        </Map>
        <Map name="lon">
            <Float32/>
            <dimension name="lon" size="701"/>
        </Map>
    </Grid>
    <Grid name="DOPy">
        <Attribute name="nameNotUsed" type="OtherXML">
            <Definition xmlns="http://www.opengis.net/wcs/1.1"
                    xmlns:ows="http://www.opengis.net/ows/1.1"
                    >
                <ows:AnyValue/>
            </Definition>
            <owcs:InterpolationMethods xmlns:owcs="http://www.opengis.net/wcs/1.1/ows" >
                <owcs:DefaultMethod>nearest</owcs:DefaultMethod>
            </owcs:InterpolationMethods>
        </Attribute>
        <Attribute name="long_name" type="String">
            <value>latitudinal dilution of precision</value>
        </Attribute>
        <Attribute name="comment" type="String">
            <value>The latitudinal dilution of precision (DOPy) represents the\\012contribution of the radars&apos;
                configuration geometry to\\012uncertainty in the northward velocity estimate (v). DOPy is a\\012direct
                multiplier of the standard error in obtaining the\\012standard deviation for the northward velocity
                estimate from the\\012least squares best fit. DOPx and DOPy are commonly used to\\012obtain the
                geometric dilution of precision\\012(GDOP = sqrt(DOPx^2 + DOPy^2)), a useful metric for
                filtering\\012errant velocities due to poor geometry.
            </value>
        </Attribute>
        <Attribute name="_FillValue" type="Int16">
            <value>-32768</value>
        </Attribute>
        <Attribute name="scale_factor" type="Float32">
            <value>0.009999999776</value>
        </Attribute>
        <Array name="DOPy">
            <Int16/>
            <dimension name="time" size="1"/>
            <dimension name="lat" size="460"/>
            <dimension name="lon" size="701"/>
        </Array>
        <Map name="time">
            <Int32/>
            <dimension name="time" size="1"/>
        </Map>
        <Map name="lat">
            <Float32/>
            <dimension name="lat" size="460"/>
        </Map>
        <Map name="lon">
            <Float32/>
            <dimension name="lon" size="701"/>
        </Map>
    </Grid>
    <Array name="site_lat">
        <Attribute name="long_name" type="String">
            <value>Contributing radar site latitudes</value>
        </Attribute>
        <Attribute name="standard_name" type="String">
            <value>latitude</value>
        </Attribute>
        <Attribute name="units" type="String">
            <value>degrees_north</value>
        </Attribute>
        <Float32/>
        <dimension name="nSites" size="27"/>
    </Array>
    <Array name="site_lon">
        <Attribute name="long_name" type="String">
            <value>Contributing radar site longitudes</value>
        </Attribute>
        <Attribute name="standard_name" type="String">
            <value>longitude</value>
        </Attribute>
        <Attribute name="units" type="String">
            <value>degrees_east</value>
        </Attribute>
        <Float32/>
        <dimension name="nSites" size="27"/>
    </Array>
    <Array name="procParams">
        <Attribute name="long_name" type="String">
            <value>RTV processing parameters</value>
        </Attribute>
        <Attribute name="comment" type="String">
            <value>\\01201) Maximum GDOP threshold\\01202) Maximum speed threshold (cm s-1)\\01203) Minimum number of
                sites required\\01204) Minimum number of radials required\\01205) Maximum angular gap to interpolate
                radial\\012 data over (degrees, 0 = no interpolation)\\01206) Maximum gap in range to interpolate
                radial\\012 data over (range-resolution, 0 = no interpolation)\\01207) Spatial search radius for radial
                solutions (km)
            </value>
        </Attribute>
        <Float32/>
        <dimension name="nProcParam" size="7"/>
    </Array>
 
</Dataset>
 
</pre>
 
==== XSLT ====
==== RDF ====

Latest revision as of 21:23, 24 April 2009

The DAP Relational Database Server II (DRDS-II) is a (as yet to funded) project that will provide a DAP service layer for relational databases systems. Previously this was (partially) accomplished by a Java servlet known as the DODS Relational Database Server (DRDS).

Overview

Automated catalog generation vs. external configuration

Should the DRDS-II interrogate the database to learn the table and key structures so that it can automatically build a catalog of DAP data objects that represent the database holdings? Or, should the DRDS-II rely (as it's predecessor did) on having the operator develop a DDS/DDX (or some other configuration item) for each data holding?

Data model representation: Tables/Queries as Sequences

In the world of the RDBMS everything is structurally a row set: A collection (tuple) of columns (variables) whose length my not be known until the content is delivered in total. Tables are row sets. A database view is a row set. SQL queries return row sets. SQL JOIN operations take row sets' as input and produce row sets.

Row sets map naturally to the DAP Sequence data type, thus a reasonable representation of an SQL query is a Sequence: A repeating tuple of unknown length.

When a database contains multiple tables or views, each one could be represented as a DAP Sequence. Thus a DDS might contain multiple Sequences each representing a single table or view in the RDBMS:

Dataset {
    Sequence {
        String FirstName;
        String LastName;
        String PhoneNumber;
    } Authors;

    Sequence {
        String Title;
        String Publisher;
        Int16  Pages;
        String   CopyrightDate;
        String   ISBN;
    } Books;

} Inventory;

Databases are typically much more complex. In our example above it would more likely that the Books table contains one or more foreign keys that references the authors of the book. So how to capture this? If we simply add the key field to the Sequence how do users of the system know how to construct queries that can return the data they want? Would this representation allow them to make requests that could return data with the key relationships expressed in the DAP structure (I don't think so) How do we prevent them from making requests the create problems for the RDBMS by creating, via the DAP constraint expression, unreasonable JOIN requests. Additionally, this very flat representation doesn't clearly establish the relationships between the tables.

On possible solution is to represent the databse tables as a series of nested sequences:

Dataset {

    Sequence {
        String Title;
        String Publisher;
        Int16  Pages;
        String   CopyrightDate;
        String   ISBN;
        Sequence {
            String FirstName;
            String LastName;
            String PhoneNumber;
        } Authors;
    } Books;

} Inventory;

Does this actually represent the case of foreign keys?

Tasks

A server that adds a DAP interface to a RDBMS needs:

  1. A component that can translate a DAP query into an SQL query string. This might happen at the string level by simply converting one to the other. The DRDS accomplished this by processing the DAP query string (marking variables in a DDS instance as projected and parsing the selection part of the constraint into Clause objects) and then working with the in memory objects (DDS and Clause objects) to build the SQL query.
  2. A mechanism through which the RDBMS holdings (a collection of one or more tables and views) can be represented as a collection of DAP data sets. For this document we will refer to this as catalog generation. This is inexorably connected to the type mapping activities explained next.
  3. A mapping between the data types found in the RDBMS to the appropriate DAP data types. For many simple/atomic type this is simple: An SQL FLOAT maps naturally to a DAP Float64. For other types, such as an database table with foreign keys the mapping is less straightforward. This activity s further complicated by the fact that nearly every RDBMS implementation contains a number of useful, yet proprietary data types. Thus a proper data model might have to be generated for each RDBMS encountered.

Previous Design/Implementation

The first DRDS (DODS Relational Database Server) was implemented as a Java Servlet. It relied on the Java-DODS implementation of the DAP to provide the DAP type classes with constraint expression evaluation and data value serialization. Some documentation can be found here:


Important features/activities:

  • The server used filesystem directories containing DDS and DAS documents to represent the holdings in the RDBMS. These files were used to generate the DDS and DAS responses.
  • The opendap.servers.sql.sqlCEEval.getSQLQueries() method that takes a constrained DDS object and interrogates it to form an SQL query.
  • Each table or view in the database could only be represented as a data set containing a singe DAP Sequence.
  • The individual DAP type classes implement the read() and serialize() methods that extracts values from the SQL query result and write the values to the client. The DAP Sequence implementation manages which "row" is being read from the SQL response object.

Despite its limitations and lack of ongoing support the DRDS was useful for a number of data centers and continues to be used today. However, the DRDS had many drawbacks:

  • It required the operator to engage in a significant configuration steps:
    • Locating a JDBC driver for their database implementation.
    • Configuring the DRDS to correctly use the JDBC driver.
    • Hand writing the DDS and DAS documents for each table or view in the database for which DAP 2 services were to be provided. This in effect placed the operator of the server in charge of mapping the different types of data held in the database tables into the different types in the DAP data model. The DRDS implementation only allowed certain mappings (as many of the possible combinations were non-sensical), thus if the operator made a poor mapping (For example creating a floating point variable in the DDS and then trying to read a SQL CHAR type into it) the server would not function correctly.
  • It could not automatically build a catalog of the RDBMS holdings. (This was done by the operator as described above)
  • The representation of the RDBMS holds was limited to a single table per DAP data set. Thus each DDS in the catalog contained a single Sequence representing a single table or view from within the RDBMS. Since most RDBMS holds are a collection of tables linked together through keys, this single Sequence representation was a very "flat" view of the RDBMS which many users found particularly restrictive. Making different views of the database alleviated the effects of this limitation to a certain extent, but typically caused some (many?) data values to be sent in a repetitive manner.

Data model representation

Mapping the a the SQL data model to the DAP data model is problematic due to the diversity of the implementations of an SQL database.


Atomic (Simple) Types

Tables as Sequences

Single Tables

Multiple Tables

Multiple Tables as Nested Sequences

Other Complex Types

Relational Database Data Types

Accessing data in an RDBMS is often a many layered affair. Many RDBMS implementations provide a native API library that can be used with a common programming language such as C, C++, C#, Visual Basic, or even Java. These API's interact directly with the RDBMS and provide the maximum level of flexibility, control and access. If one was using a native API to work with a RDBMS to get data then there would be a mapping from the native RDBMS data types to the language data types:


Native RDBMS Data Types ---> C++ Data Types


However, most software that works with RDMSs does so through a database connectivity API. The two most common are the Open Database Connectivity (ODBC) API and the Java Database Connectivity (JDBC) API. Using one of these database connectivity APIs adds a layer of data type mapping to the process:


Native RDBMS Data Types ---> Database Connectivity API Data Types ---> C++ Data Types


To complete the picture, generating DAP data objects requires the finally mapping from the programming language data types in to the DAP data model:


Native RDBMS Data Types ---> Database Connectivity API Data Types ---> C++ Data Types ---> DAP Data Types


For simple/atomic types such as integers an booleans this doesn't require much thought. For more complex types it may require both thought ad careful development to preserve the original semantics of the RDBMS data type across the various mappings and into the appropriate DAP data type. Even then the DAP data model may not have a data type that directly captures the semantics of the original type. For example PostgreSQL has a number of geometric types (such as point, box, and circle) whose content can be held in DAP types, but the semantic meaning (these two floating point values represent a point on a cartesian plain) is not explicit in the DAP object holding the values. That information can only be included in the metadata associated with the instance of the DAP variable.



Database Connectivity APIs





ODBC Data Types





JDBC Data Types

The DRDS used a JDBC connection to retrieve data from a relational database. It is important to note that their are several layers of type translation happening in this:

Database -> JDBC -> Java -> DODS

The Database types are the native types for the particular database that is being read from. The translation from Database->JDBC was handled before the data arrived at the DRDS (most likely by the JDBC Drivers). The mapping of JDBC type to DODS types (the intermediate Java types happen in the process) looked like this:

Mapping from JDBC Types to DODS Types
JDBC Type DAP Type
TINYINT DByte
SMALLINT DInt16
INTEGER DInt32
BIGINT DInt32 **NO SENSIBLE MAPPING (Need DInt64)
REAL DFloat32
FLOAT DFloat64
DOUBLE DFloat64
DECIMAL DFloat64 **NO SENSIBLE MAPPING (Need Some Kind Monsterous Floating point value)
NUMERIC DFloat64 **NO SENSIBLE MAPPING (ibid)
BIT DBoolean
CHAR DString
VARCHAR DString
LONGVARCHAR Implemented to be read into a DString, although it is a "BLOB" type and might be better represented as a DArray(of bytes).
BINARY DArray(of bytes)
VARBINARY DArray(of bytes)
LONGVARBINARY DArray(of bytes)
DATE DString
TIME DString
TIMESTAMP DString

Native SQL Data Types by Implementation





PostgreSQL Data Types

Todo:
 !! This section needs to be updated and otherwise corrected. !!
Boolean and Binary Types
Data Type Description Standardization Logical DAP data type association.
boolean, bool A single true or false value. SQL99 Boolean
bit(n) An n -length bit string (exactly n binary bits). SQL92 None
bit varying(n), varbit(n) A variable n -length bit string (up to n binary bits) SQL92 None
Character Types
Data Type Description Storage Standardization Logical DAP data type association.
character (n ), char(n ) A fixed n -length character string. (4+n) bytes SQL89 String
character varying(n), varchar(n) A variable length character string of up to n characters. Up to (4+n) bytes SQL92 String
text A variable length character string, of unlimited length. Variable PostgreSQL-specific String
Numeric Types
Data Type Description Storage Standardization Logical DAP data type association.
smallint, int2 A signed 2-byte integer 2 bytes SQL89 Int16
integer, int, int4 A signed, fixed-precision 4-byte number. 4 bytes SQL92 Int32
bigint, int8 A signed 8-byte integer, up to 18 digits in length. 8 bytes PostgreSQL-specific None (Need Int64)
real, float4 A 4-byte floating point number. 4 bytes SQL89 Float32
double precision, float8, float An 8-byte floating point number 8 bytes SQL89 Float64
numeric(p,s), decimal(p,s) An exact numeric type with arbitrary precision p, and scale s. Variable SQL99 None
money A fixed precision, U.S.-style currency. 4 bytes PostgreSQL-specific, deprecated. None
serial An auto-incrementing 4-byte integer. 4 bytes PostgreSQL-specific. None
Date and Time Types
Data Type Description Storage Standardization Logical DAP data type association.
date A calendar date (day, month, year). 4 bytes SQL92 String
time The time of day. 4 bytes SQL92 String
time with time zone The time of day, including time zone information. 4 bytes SQL92 String
timestamp (includes time zone) Both date and time. 8 bytes SQL92 String
interval An arbitrary specified length of time 12 bytes SQL92 String
Geometric Types
Data Type Description Storage Standardization Logical DAP data type association.
box A rectangular box in a 2D plane. 32 bytes PostgreSQL-specific None ([2][2] Array of Float32)
line An infinite line in a 2D plane. ?? bytes PostgreSQL-specific None ([2][2] Array of Float32)
lineseg A finite line segment in a 2D plane. 32 bytes PostgreSQL-specific None ([2][2] Array of Float32)
circle A circle with center and radius. 24 bytes PostgreSQL-specific None ([3]Array of Float32)
path Open and closed geometric paths in a two-dimensional plane . 4+32*n bytes PostgreSQL-specific None (Array of Float32)
point geometric point in a 2D plane 16 bytes PostgreSQL-specific None ([2] Array of Float32)
polygon A closed geometric path in a 2D plane 4+32*n bytes PostgreSQL-specific None (Array of Float32)
Network Types
Data Type Description Standardization Logical DAP data type association.
cdir An IP network specification PostgreSQL-specific None
inet A network IP address, with optional subnet bits. PostgreSQL-specific None
macaddr A MAC address (e.g., an Ethernet card's hardware address). PostgreSQL-specific None
System Types
Data Type Description Standardization Logical DAP data type association.
oid An object (row) identifier. PostgreSQL-specific None
xid A transaction identifier PostgreSQL-specific None





Transact-SQL (Microsoft)

Todo:
 !! This section needs to be updated and otherwise corrected. !!
Type Description Storage Bytes DAP equiv.
bigint Integer (whole number) data from -2^63 (-9,223,372,036,854,775,808) through 2^63-1 (9,223,372,036,854,775,807). 8 bytes none
int Integer (whole number) data from -2^31 (-2,147,483,648) through 2^31 - 1 (2,147,483,647). 4 bytes
numeric Functionally equivalent to decimal.
decimal Fixed precision and scale numeric data from -10^38 +1 through 10^38 –1.
bit Integer data with either a 1 or 0 value
smallint Integer data from -2^15 (-32,768) through 2^15 - 1 (32,767). 2 bytes
tinyint Integer data from 0 through 255 1 bytes
smallmoney Monetary data values from -214,748.3648 through +214,748.3647, with accuracy to a ten-thousandth of a monetary unit.
money Monetary data values from -2^63 (-922,337,203,685,477.5808) through 2^63 - 1 (+922,337,203,685,477.5807), with accuracy to a ten-thousandth of a monetary unit.
float Floating precision number data with the following valid values: -1.79E + 308 through -2.23E - 308, 0 and 2.23E + 308 through 1.79E + 308. 4 or 8 bytes
real Floating precision number data with the following valid values: -3.40E + 38 through -1.18E - 38, 0 and 1.18E - 38 through 3.40E + 38. 4 bytes
date
datetimeoffset
datetime2
smalldatetime Date and time data from January 1, 1900, through June 6, 2079, with an accuracy of one minute.
datetime Date and time data from January 1, 1753, through December 31, 9999, with an accuracy of three-hundredths of a second, or 3.33 milliseconds.
time
char Fixed-length non-Unicode character data with a maximum length of 8,000 characters.
varchar Variable-length non-Unicode data with a maximum of 8,000 characters.
next Variable-length non-Unicode data with a maximum length of 2^31 - 1 (2,147,483,647) characters
nchar Fixed-length Unicode data with a maximum length of 4,000 characters
nvarchar Variable-length Unicode data with a maximum length of 4,000 characters. sysname is a system-supplied user-defined data type that is functionally equivalent to nvarchar(128) and is used to reference database object names.
ntext Variable-length Unicode data with a maximum length of 2^30 - 1 (1,073,741,823) characters.
binary Fixed-length binary data with a maximum length of 8,000 bytes.
varbinary Variable-length binary data with a maximum length of 8,000 bytes.
image Variable-length binary data with a maximum length of 2^31 - 1 (2,147,483,647) bytes.
cursor A reference to a cursor.
timestamp A database-wide unique number that gets updated every time a row gets updated.
hierarchyid
uniquieidentifier A globally unique identifier (GUID).
sql_variant
xml
table

Template

Types

Data Type Description Standardization Logical DAP data type association.

Desired Features

Implementation Target