<?xml version="1.0" encoding="UTF-8"?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
	targetNamespace="http://definition.nexusformat.org/nxdl/3.1"
	xmlns:nxdl="http://definition.nexusformat.org/nxdl/3.1"
	elementFormDefault="qualified">

	<xs:annotation>
		<xs:documentation>
			..
				NeXus - Neutron and X-ray Common Data Format
				
				Copyright (C) 2009-2026 NeXus International Advisory Committee (NIAC)
				
				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 3 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
				
				For further information, see http://www.nexusformat.org
		</xs:documentation>
	</xs:annotation>
	
	<!--
		anyUnitsAttr: specifies the type of content that goes into a units="" attribute
		primitiveType: specifies the type of content that goes into a type="" attribute of a field or attribute
		-->
	
	<!-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
	
	<xs:simpleType name="anyUnitsAttr">
		<xs:annotation>
			<xs:documentation>
				Unit categories in NXDL specifications describe the expected type of units for a NeXus field.
				
				They should describe valid units consistent with
				the manual section on NeXus units (based on UDUNITS).

				Units are not validated by NeXus.
			</xs:documentation>
		</xs:annotation>
		<xs:union memberTypes="
			nxdl:NX_ANGLE
			nxdl:NX_ANY
			nxdl:NX_AREA
			nxdl:NX_CROSS_SECTION
			nxdl:NX_CHARGE
			nxdl:NX_CURRENT
			nxdl:NX_DIMENSIONLESS
			nxdl:NX_EMITTANCE
			nxdl:NX_ENERGY
			nxdl:NX_FLUX
			nxdl:NX_FREQUENCY
			nxdl:NX_LENGTH
			nxdl:NX_MASS
			nxdl:NX_MASS_DENSITY
			nxdl:NX_MOLECULAR_WEIGHT
			nxdl:NX_PER_AREA
			nxdl:NX_PER_LENGTH
			nxdl:NX_PERIOD
			nxdl:NX_POWER 
			nxdl:NX_PRESSURE
			nxdl:NX_PULSES
			nxdl:NX_COUNT
			nxdl:NX_SCATTERING_LENGTH_DENSITY
			nxdl:NX_SOLID_ANGLE
			nxdl:NX_TEMPERATURE
			nxdl:NX_TIME
			nxdl:NX_TIME_OF_FLIGHT
			nxdl:NX_TRANSFORMATION
			nxdl:NX_UNITLESS
			nxdl:NX_VOLTAGE
			nxdl:NX_VOLUME
			nxdl:NX_WAVELENGTH
			nxdl:NX_WAVENUMBER
			xs:string
			" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_ANGLE">
		<xs:annotation>
			<xs:documentation>
				units of angle
				<xs:element name="example">rad</xs:element>
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_ANY">
		<xs:annotation>
			<xs:documentation>
				units for things like logs that aren't picky on units
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_AREA">
		<xs:annotation>
			<xs:documentation>
				units of area
				<xs:element name="example">m^2</xs:element>
				<xs:element name="example">barns</xs:element>
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_COUNT">
		<xs:annotation>
			<xs:documentation>
				units of quantity of item(s) such as number of photons,
				neutrons, pulses, or other counting events
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_CROSS_SECTION">
		<xs:annotation>
			<xs:documentation>
				units of area (alias of NX_AREA)
				<xs:element name="example">barn</xs:element>
			</xs:documentation>
		</xs:annotation>
		<xs:union memberTypes="nxdl:NX_AREA" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_CHARGE">
		<xs:annotation>
			<xs:documentation>
				units of electrical charge
				<xs:element name="example">C</xs:element>
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_CURRENT">
		<xs:annotation>
			<xs:documentation>
				units of electrical current
				<xs:element name="example">A</xs:element>
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_DIMENSIONLESS">
		<xs:annotation>
			<xs:documentation>
				units for fields where the units cancel out
				(NOTE: not the same as NX_UNITLESS)
				<xs:element name="example">m/m</xs:element>
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_EMITTANCE">
		<xs:annotation>
			<xs:documentation>
				units of emittance (``length * angle``) of a
				radiation source
				<xs:element name="example">nm*rad</xs:element>
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_ENERGY">
		<xs:annotation>
			<xs:documentation>
				units of energy
				<xs:element name="example">J</xs:element>
				<xs:element name="example">keV</xs:element>
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_FLUX">
		<xs:annotation>
			<xs:documentation>
				units of flux
				<xs:element name="example">1/s/cm^2</xs:element>
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_FREQUENCY">
		<xs:annotation>
			<xs:documentation>
				units of frequency
				<xs:element name="example">Hz</xs:element>
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_LENGTH">
		<xs:annotation>
			<xs:documentation>
				units of length
				<xs:element name="example">m</xs:element>
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_MASS">
		<xs:annotation>
			<xs:documentation>
				units of mass
				<xs:element name="example">g</xs:element>
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_MASS_DENSITY">
		<xs:annotation>
			<xs:documentation>
				units of mass density
				<xs:element name="example">g/cm^3</xs:element>
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_MOLECULAR_WEIGHT">
		<xs:annotation>
			<xs:documentation>
				units of molecular weight
				<xs:element name="example">g/mol</xs:element>
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_PER_AREA">
		<xs:annotation>
			<xs:documentation>
				units of 1/length^2
				<xs:element name="example">1/m^2</xs:element>
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_PER_LENGTH">
		<xs:annotation>
			<xs:documentation>
				units of 1/length
				<xs:element name="example">1/m</xs:element>
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_PERIOD">
		<xs:annotation>
			<xs:documentation>
				units of time, period of pulsed source
				(alias to `NX_TIME`)
				<xs:element name="example">us</xs:element>
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_POWER">
		<xs:annotation>
			<xs:documentation>
				units of power
				<xs:element name="example">W</xs:element>
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_PRESSURE">
		<xs:annotation>
			<xs:documentation>
				units of pressure
				<xs:element name="example">Pa</xs:element>
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_PULSES">
		<xs:annotation>
			<xs:documentation>
				DEPRECATED: see NX_COUNT

				units of clock pulses (alias to `NX_NUMBER`)
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_SCATTERING_LENGTH_DENSITY">
		<xs:annotation>
			<xs:documentation>
				units of scattering length density
				<xs:element name="example">m/m^3</xs:element>
			</xs:documentation>
		</xs:annotation>
		<!-- isn't this an alias of NX_PER_AREA?
			Could also be alias of NX_LENGTH (cm^2/atom) -->
		<!-- <xs:union memberTypes="nxdl:NX_PER_AREA nxdl:NX_LENGTH" /> -->
		<xs:restriction base="xs:string" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_SOLID_ANGLE">
		<xs:annotation>
			<xs:documentation>
				units of solid angle
				<xs:element name="example">sr</xs:element>
				<xs:element name="example">steradian</xs:element>
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_TEMPERATURE">
		<xs:annotation>
			<xs:documentation>
				units of temperature
				<xs:element name="example">K</xs:element>
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_TIME">
		<xs:annotation>
			<xs:documentation>
				units of time
				<xs:element name="example">s</xs:element>
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_TIME_OF_FLIGHT">
		<xs:annotation>
			<xs:documentation>
				units of (neutron) time of flight
				(alias to `NX_TIME`)
				<xs:element name="example">s</xs:element>
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_TRANSFORMATION">
		<xs:annotation>
			<xs:documentation>
				units of the specified transformation
				
				could be any of these: ``NX_LENGTH``, ``NX_ANGLE``, or ``NX_UNITLESS``
				
				There will be one or more transformations defined by one or more fields
				for each transformation.  The units type ``NX_TRANSFORMATION`` designates the
				particular axis generating a transformation (e.g. a rotation axis or a translation
				axis or a general axis).   ``NX_TRANSFORMATION`` designates the
				units will be appropriate to the type of transformation,
				indicated in the :ref:`NXtransformations` base class
				by the ``transformation_type`` value:
				
				* ``NX_LENGTH`` for ``translation``
				* ``NX_ANGLE`` for ``rotation`` 
				* ``NX_UNITLESS`` for axes for which no transformation type is specified.
			</xs:documentation>
		</xs:annotation>
		<xs:union memberTypes="
			nxdl:NX_LENGTH 
			nxdl:NX_ANGLE 
			nxdl:NX_UNITLESS
			" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_UNITLESS">
		<xs:annotation>
			<xs:documentation>
				for fields that don't have a unit (e.g. hkl) so that they don't
				inherit the wrong units (NOTE: not the same as NX_DIMENSIONLESS)
				<xs:element name="example">""</xs:element>
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_VOLTAGE">
		<xs:annotation>
			<xs:documentation>
				units of voltage
				<xs:element name="example">V</xs:element>
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_VOLUME">
		<xs:annotation>
			<xs:documentation>
				units of volume
				<xs:element name="example">m^3</xs:element>
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_WAVELENGTH">
		<xs:annotation>
			<xs:documentation>
				units of wavelength
				<xs:element name="example">angstrom</xs:element>
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_WAVENUMBER">
		<xs:annotation>
			<xs:documentation>
				units of wavenumber or Q
				<xs:element name="example">1/nm</xs:element>
				<xs:element name="example">1/angstrom</xs:element>
			</xs:documentation>
		</xs:annotation>
		<!-- isn't this an alias of NX_PER_LENGTH? -->
		<!-- <xs:union memberTypes="nxdl:NX_PER_LENGTH" /> -->
		<xs:restriction base="xs:string" />
	</xs:simpleType>
	
	<!-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->

	<xs:simpleType name="primitiveType">
		<xs:annotation>
			<xs:documentation>any valid NeXus field or attribute type</xs:documentation>
		</xs:annotation>
		<xs:union memberTypes="
			nxdl:ISO8601
			nxdl:NX_BINARY
			nxdl:NX_BOOLEAN
			nxdl:NX_CCOMPLEX
			nxdl:NX_CHAR
			nxdl:NX_COMPLEX
			nxdl:NX_DATE_TIME
			nxdl:NX_FLOAT
			nxdl:NX_INT
			nxdl:NX_NUMBER
			nxdl:NX_PCOMPLEX
			nxdl:NX_POSINT
			nxdl:NX_QUATERNION
			nxdl:NX_UINT
			nxdl:NX_CHAR_OR_NUMBER
			"/>
	</xs:simpleType>
	
	<xs:simpleType name="NX_CHAR">
		<xs:annotation>
			<xs:documentation>
				A string of characters. The preferred string encoding is :index:`UTF-8`. 
				This is the default field type.
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_FLOAT">
		<xs:annotation>
			<xs:documentation>any representation of a floating point number</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:float" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_INT">
		<xs:annotation>
			<xs:documentation>any representation of an integer number</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:integer" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_UINT">
		<xs:annotation>
			<xs:documentation>any representation of an unsigned integer number (includes zero)</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:unsignedInt" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_POSINT">
		<xs:annotation>
			<xs:documentation>any representation of a positive integer number (greater than zero)</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:positiveInteger" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_NUMBER">
		<xs:annotation>
			<xs:documentation>any valid NeXus number representation</xs:documentation>
		</xs:annotation>
		<xs:union memberTypes="
			nxdl:NX_INT 
			nxdl:NX_UINT 
			nxdl:NX_POSINT 
			nxdl:NX_FLOAT
			" />
	</xs:simpleType>

	<xs:simpleType name="list_of_doubles">
		<xs:list itemType='xs:double' />
	</xs:simpleType>

	<xs:simpleType name="NX_CCOMPLEX">
		<xs:annotation>
			<xs:documentation>
			Compound type cartesian representation of complex numbers (real and
			imaginary parts) in NeXus.
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="nxdl:list_of_doubles">
			<xs:length value='2' />
		</xs:restriction>
	</xs:simpleType>

	<xs:simpleType name="NX_PCOMPLEX">
		<xs:annotation>
			<xs:documentation>
				Compound type polar representation of complex numbers 
				(amplitude and phase *in radians*) in NeXus.
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="nxdl:list_of_doubles">
			<xs:length value='2' />
		</xs:restriction>
	</xs:simpleType>
	
	<xs:simpleType name="NX_COMPLEX">
		<xs:annotation>
			<xs:documentation>
				Compound type representation of complex numbers (either
				cartesian or polar form) in NeXus.
			</xs:documentation>
		</xs:annotation>
		<xs:union memberTypes="
			nxdl:NX_CCOMPLEX  
			nxdl:NX_PCOMPLEX
			" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_QUATERNION">
		<xs:annotation>
			<xs:documentation>
				Compound type representation of quaternion numbers 
				(real,i,j,k) in NeXus.
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="nxdl:list_of_doubles">
			<xs:length value='4' />
		</xs:restriction>
	</xs:simpleType>
	
	<xs:simpleType name="NX_DATE_TIME">
		<xs:annotation>
			<xs:documentation>
			Alias for the ``ISO8601`` date/time stamp.
			It is recommended to add an explicit time zone,
			otherwise the local time zone is assumed per ISO8601.
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="nxdl:ISO8601" />
	</xs:simpleType>
	
	<xs:simpleType name="ISO8601">
		<xs:annotation>
			<xs:documentation>
			ISO8601 date/time stamp.
			It is recommended to add an explicit time zone,
			otherwise the local time zone *is assumed* per ISO8601.
			The norm is that if there is no time zone, it is assumed
			local time, however, when a file moves from one country to
			another it is undefined. If the local time zone is written,
			the ambiguity is gone.
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:dateTime" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_BOOLEAN">
		<xs:annotation>
			<xs:documentation>true/false value ( true | 1 | false | 0 )</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:boolean" />
	</xs:simpleType>
	
	<xs:simpleType name="NX_BINARY">
		<xs:annotation>
			<xs:documentation>any representation of binary data - if text, line terminator is [CR][LF]</xs:documentation>
		</xs:annotation>
		<!-- TODO Is this the way to describe pure binary?  uint8, byte, hex64binary -->
		<!-- TODO Should be a uint8 but this does not seem to be allowed.  Using xs:unsignedByte instead. -->
		<xs:restriction base="xs:unsignedByte" />
	</xs:simpleType>

	<xs:simpleType name="NX_CHAR_OR_NUMBER">
		<xs:annotation>
			<xs:documentation>Any valid character string or NeXus number representation</xs:documentation>
		</xs:annotation>
		<xs:union memberTypes="
			nxdl:NX_NUMBER
			nxdl:NX_CHAR
			" />
	</xs:simpleType>

</xs:schema>
