I've created a meta model to store technical measurements, in order to manage them in Java after I parsed them with JAXB.
I want to support scalars (angle, length, temperature, etc.) and also vectors (like direction).
As a bonus I'd also like to support matrices (maybe for rotations). Below an example model.
<measure name="X">
<properties>
<property name="description" value="length"/>
<property name="unit" value="mm"/>
<property name="tolerance" value="1"/>
</properties>
<scalar>150.157</scalar>
<vector/>
<matrix/>
</measure>
I don't like the current approach where I have three optional entries for the three possible value types.
Are there better, unified approaches without the use of optional fields that are also easily parsable?
One of the approaches is to use substitution groups. You declare a global element, say, value
, of some ValueType
and reference it where needed.
Then you add further types (like ScalarType
, VectorType
, MatrixType
) which extend ValueType
and declare global elements scalar
, vector
, matrix
with substitutionGroup="tns:value"
. This would mean that these elements may subsitute value
.
In your MeasureType
you will simply include <xs:element ref="value"/>
and this will allow scalar
, vector
, matrix
appear instead.
XJC can compile this kind of schemas and JAXB works quite fine with substitution groups. Youll get a
JAXBElement`-typed property.
Here is an example of schema which uses this approach:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema targetNamespace="http://www.opengis.net/ogc"
xmlns:ogc="http://www.opengis.net/ogc"
xmlns:gml="http://www.opengis.net/gml"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
version="1.1.3">
<!--
filter is an OGC Standard.
Copyright (c) 2002,2003,2004,2010 Open Geospatial Consortium.
To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
Updated: 2012-07-21
-->
<xsd:element name="Add" type="ogc:BinaryOperatorType"
substitutionGroup="ogc:expression"/>
<xsd:element name="Sub" type="ogc:BinaryOperatorType"
substitutionGroup="ogc:expression"/>
<xsd:element name="Mul" type="ogc:BinaryOperatorType"
substitutionGroup="ogc:expression"/>
<xsd:element name="Div" type="ogc:BinaryOperatorType"
substitutionGroup="ogc:expression"/>
<xsd:element name="PropertyName" type="ogc:PropertyNameType"
substitutionGroup="ogc:expression"/>
<xsd:element name="Function" type="ogc:FunctionType"
substitutionGroup="ogc:expression"/>
<xsd:element name="Literal" type="ogc:LiteralType"
substitutionGroup="ogc:expression"/>
<xsd:element name="expression" type="ogc:ExpressionType" abstract="true"/>
<!-- <xsd:complexType name="ExpressionType" abstract="true" mixed="true"/>
-->
<xsd:complexType name="ExpressionType" abstract="true"/>
<xsd:complexType name="BinaryOperatorType">
<xsd:complexContent>
<xsd:extension base="ogc:ExpressionType">
<xsd:sequence>
<xsd:element ref="ogc:expression" minOccurs="2" maxOccurs="2"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="FunctionType">
<xsd:complexContent>
<xsd:extension base="ogc:ExpressionType">
<xsd:sequence>
<xsd:element ref="ogc:expression" minOccurs="0"
maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="LiteralType">
<xsd:complexContent mixed="true">
<xsd:extension base="ogc:ExpressionType">
<xsd:sequence>
<xsd:any minOccurs="0"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="PropertyNameType">
<xsd:complexContent mixed="true">
<xsd:extension base="ogc:ExpressionType"/>
</xsd:complexContent>
</xsd:complexType>
</xsd:schema>