Working with other API specs
XML Integration
Overview
Taxi provides XML format support through model annotations, enabling:
- XML reading and writing with semantic types
- Element and attribute mapping
- Collection handling
- Expression evaluation
Describing XML using Taxi
It’s possible to model XML structures directly in Taxi.
If you’re working with an existing schema - such as an Xsd, you may prefer adding type definitions into your XSD
Add the Xml annotation to models that represent XML data:
import com.orbitalhq.formats.Xml
@Xml
model Person {
firstName: FirstName inherits String
lastName: LastName inherits String
}
Attributes vs Elements
By default, fields are mapped to XML elements. To map a field to an XML attribute:
import com.orbitalhq.formats.Xml
import lang.taxi.xml.XmlAttribute
@Xml
model Actor inherits Person {
@XmlAttribute
id: ActorId
fullName: FullName
}
Results in:
<?xml version='1.0' encoding='UTF-8'?>
<Actor id="3">
<fullName>Jimmy Smith</fullName>
</Actor>Collections
Array fields automatically map to repeated XML elements:
@Xml
model Movie {
actors: Actor[]
}
Results in:
<?xml version='1.0' encoding='UTF-8'?>
<Movie>
<actors id="1">
<firstName>Mel</firstName>
<lastName>Gibson</lastName>
</actors>
<actors id="2">
<firstName>Jack</firstName>
<lastName>Spratt</lastName>
</actors>
</Movie>Expressions
Models can include computed fields using expressions:
import com.orbitalhq.formats.Xml
import lang.taxi.xml.XmlAttribute
@Xml
model Actor {
firstName: FirstName inherits String
lastName: LastName inherits String
fullName: FullName inherits String = FirstName + ' ' + LastName
}
Expression Handling
- When serializing: Expression values are written as normal elements
Generating taxi from an Xsd
The taxi compiler will generate a Taxi from an XSD document .
<xsd:schema
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:taxi="http://taxilang.org/"
targetNamespace="http://tempuri.org/PurchaseOrderSchema.xsd">
<xsd:complexType name="CountryInfo">
<xsd:sequence>
<!-- Create new semantic type -->
<xsd:element name="ISOCode" type="xsd:string"
taxi:createsType="com.foo.IsoCode"/>
<!-- Reference existing semantic type -->
<xsd:element name="Name" type="xsd:string"
taxi:type="com.foo.CountryName"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>Namespace URL
Note the trailing slash in the namespace URL - xmlns:taxi="http://taxilang.org/ is required.
Adding type annotations
Use the taxi:type annotation within your XSD elements to map fields to existing types:
<xsd:complexType name="CountryInfo">
<xsd:sequence>
<xsd:element name="ISOCode" type="xsd:string" taxi:type="com.foo.IsoCode"/>
<xsd:element name="Name" type="xsd:string" taxi:type="com.foo.CountryName"/>
<xsd:element name="CapitalCity" type="xsd:string" taxi:type="com.foo.CapitalCityName" />
</xsd:sequence>
</xsd:complexType>Would generate:
namespace org.tempuri {
closed model CountryInfo {
ISOCode : com.foo.IsoCode
Name : com.foo.CountryName
CapitalCity : com.foo.CapitalCityName
}
}Note that the type definitions for field types are not declared - it’s expected these types exist elsewhere in your taxonomy
Mapping to an new type
Use the taxi:createType annotation within your XSD elements to map fields to new types, which generates the type definitions as well as the corresponding model.
<xsd:complexType name="CountryInfo">
<xsd:sequence>
<xsd:element name="ISOCode" type="xsd:string"
taxi:createType="com.foo.IsoCode"/>
<xsd:element name="Name" type="xsd:string"
taxi:createType="com.foo.CountryName"/>
<xsd:element name="CapitalCity" type="xsd:string"
taxi:createType="com.foo.CapitalCityName" />
</xsd:sequence>
</xsd:complexType>Would generate:
namespace com.foo {
type IsoCode inherits String
type CountryName inherits String
type CapitalCityName inherits String
}
namespace org.tempuri {
closed model CountryInfo {
ISOCode : com.foo.IsoCode
Name : com.foo.CountryName
CapitalCity : com.foo.CapitalCityName
}
}Nullable vs Mandatory fields
Optional elements (minOccurs=“0”) generate nullable fields:
<!-- Optional field -->
<xsd:element name="nickname" minOccurs="0" type="xsd:string"/>Generates:
nickname : String? // NullableRequired attributes generate non-nullable fields:
<xsd:attribute name="OrderDate" type="xsd:date" use="required"/>Generates:
@lang.taxi.xml.XmlAttribute
OrderDate : Date // Non-nullableEnums
XSD enumerations become Taxi enums:
<xsd:simpleType name="MandateClassification1Code">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="FIXE"/>
<xsd:enumeration value="USGB"/>
<xsd:enumeration value="VARI"/>
</xsd:restriction>
</xsd:simpleType>enum MandateClassification1Code {
FIXE,
USGB,
VARI
}Enum values with spaces are automatically normalized:
<xsd:enumeration value="FOO BAR"/>enum MandateClassification1Code {
FOO_BAR("FOO BAR") // Name normalized, original value preserved
}Documentation
XSD documentation annotations are preserved in generated Taxi:
<xsd:attribute name="OrderDate" type="xsd:date">
<xsd:annotation>
<xsd:documentation>The date for an order</xsd:documentation>
</xsd:annotation>
</xsd:attribute>[[ The date for an order ]]
@lang.taxi.xml.XmlAttribute
OrderDate : Date?Xml types and Taxi types
XSD primitive types map to Taxi types:
| XSD Type | Taxi Type |
|---|---|
| xsd:string | String |
| xsd:integer | Int |
| xsd:int | Int |
| xsd:long | Long |
| xsd:decimal | Decimal |
| xsd:double | Double |
| xsd:boolean | Boolean |
| xsd:date | Date |
| xsd:dateTime | DateTime |
| xsd:time | Time |