Skip to content

Guide

As in JSON, there is some default handling of the common scalars like utcDateTime:

Scalar TypeDefault EncodingEncoding name
utcDateTimexs:dateTimeTypeSpec.Xml.Encoding.xmlDateTime
offsetDateTimexs:dateTimeTypeSpec.Xml.Encoding.xmlDateTime
plainDatexs:dateTypeSpec.Xml.Encoding.xmlDate
plainTimexs:timeTypeSpec.Xml.Encoding.xmlTime
durationxs:durationTypeSpec.Xml.Encoding.xmlDuration
bytesxs:base64BinaryTypeSpec.Xml.Encoding.xmlBase64Binary

Properties of scalar types are serialized as child XML elements by default.

model Book {
id: integer;
title: string;
author: string;
}
<Book>
<id>0</id>
<title>The Great Gatsby</title>
<author>F. Scott Fitzgerald</author>
</Book>

@encodedName("application/xml", ...) or @Xml.name(...) changes how a property name appears in the XML output without affecting the TypeSpec model name.

model Book {
id: integer;
@Xml.name("book-title")
title: string;
author: string;
}
<Book>
<id>0</id>
<book-title>The Great Gatsby</book-title>
<author>F. Scott Fitzgerald</author>
</Book>

@encodedName("application/xml", ...) or @Xml.name(...) on a model changes the root element name in the XML output.

@Xml.name("XmlBook")
model Book {
id: integer;
title: string;
author: string;
}
<XmlBook>
<id>0</id>
<title>Les Miserables</title>
<author>Victor Hugo</author>
</XmlBook>

A property referencing another model is serialized as a nested XML element using the property name.

model Book {
author: Person;
}
model Person {
name: string;
}
<Book>
<author>
<name>F. Scott Fitzgerald</name>
</author>
</Book>

2.2 — Nested model with custom XML name on the model

Section titled “2.2 — Nested model with custom XML name on the model”

When the referenced model has @Xml.name or @encodedName, the property name still takes precedence for the XML element name.

model Book {
author: Person;
}
@Xml.name("XmlPerson")
model Person {
name: string;
}
<Book>
<author>
<name>F. Scott Fitzgerald</name>
</author>
</Book>

2.3 — Nested model with custom XML name on the property

Section titled “2.3 — Nested model with custom XML name on the property”

Using @Xml.name or @encodedName on the property overrides the element name for the nested model.

model Book {
@Xml.name("xml-author")
author: Person;
}
model Person {
name: string;
}
<Book>
<xml-author>
<name>F. Scott Fitzgerald</name>
</xml-author>
</Book>

By default, an array property is wrapped in a container element named after the property. Each item uses the scalar type name as its element name.

model Book {
tags: string[];
}
<Book>
<tags>
<string>fiction</string>
<string>classic</string>
</tags>
</Book>

@Xml.unwrapped removes the wrapper element. Each item is serialized using the property name as its XML element name.

model Book {
@Xml.unwrapped
tags: string[];
}
<Book>
<tags>fiction</tags>
<tags>classic</tags>
</Book>

3.3 — Wrapped primitive array with custom wrapper name

Section titled “3.3 — Wrapped primitive array with custom wrapper name”

Without @Xml.unwrapped, the array is wrapped in a container element. @Xml.name or @encodedName on the property customizes the wrapper element name.

model Book {
@Xml.name("ItemsTags")
tags: string[];
}
<Book>
<ItemsTags>
<string>fiction</string>
<string>classic</string>
</ItemsTags>
</Book>

3.4 — Unwrapped primitive array with custom item name

Section titled “3.4 — Unwrapped primitive array with custom item name”

@Xml.name or @encodedName on the property controls the element name of each item when the array is unwrapped.

model Book {
@Xml.name("tag")
@Xml.unwrapped
tags: string[];
}
<Book>
<tag>fiction</tag>
<tag>classic</tag>
</Book>

3.5 — Wrapped primitive array with custom wrapper and item names

Section titled “3.5 — Wrapped primitive array with custom wrapper and item names”

Both the wrapper element and each item element have custom names via @Xml.name or @encodedName.

@Xml.name("ItemName")
scalar tag extends string;
model Book {
@Xml.name("ItemsTags")
tags: tag[];
}
<Book>
<ItemsTags>
<ItemName>fiction</ItemName>
<ItemName>classic</ItemName>
</ItemsTags>
</Book>

By default, an array of models is wrapped in a container element named after the property. Each item uses the model name as its element name.

model Store {
books: Book[];
}
model Book {
title: string;
}
<Store>
<books>
<Book>
<title>The Great Gatsby</title>
</Book>
<Book>
<title>Les Miserables</title>
</Book>
</books>
</Store>

@Xml.unwrapped removes the wrapper element. Each item uses the property name as its element name.

model Store {
@Xml.unwrapped
books: Book[];
}
model Book {
title: string;
}
<Store>
<books>
<title>The Great Gatsby</title>
</books>
<books>
<title>Les Miserables</title>
</books>
</Store>

4.3 — Wrapped array of models with custom wrapper name

Section titled “4.3 — Wrapped array of models with custom wrapper name”

@Xml.name or @encodedName on the property customizes the wrapper element name.

model Store {
@Xml.name("AllBooks")
books: Book[];
}
model Book {
title: string;
}
<Store>
<AllBooks>
<Book>
<title>The Great Gatsby</title>
</Book>
<Book>
<title>Les Miserables</title>
</Book>
</AllBooks>
</Store>

4.4 — Unwrapped array of models with custom item name

Section titled “4.4 — Unwrapped array of models with custom item name”

@Xml.name or @encodedName on the property overrides each item’s element name when the array is unwrapped.

model Store {
@Xml.name("BookItem")
@Xml.unwrapped
books: Book[];
}
model Book {
title: string;
}
<Store>
<BookItem>
<title>The Great Gatsby</title>
</BookItem>
<BookItem>
<title>Les Miserables</title>
</BookItem>
</Store>

4.5 — Wrapped array of models with custom wrapper and item names

Section titled “4.5 — Wrapped array of models with custom wrapper and item names”

Both the wrapper element and each item element have custom names.

model Store {
@Xml.name("AllBooks")
books: Book[];
}
@Xml.name("BookItem")
model Book {
title: string;
}
<Store>
<AllBooks>
<BookItem>
<title>The Great Gatsby</title>
</BookItem>
<BookItem>
<title>Les Miserables</title>
</BookItem>
</AllBooks>
</Store>

An array model is a named model that is an array rather than a model that has an array property. It is declared with model X is Type[].

A standalone array model produces an array schema in OpenAPI. When serialized to XML, the model name becomes the root element and each item uses its type name as the element name.

model Tags is string[];
<Tags>
<string>fiction</string>
<string>classic</string>
</Tags>

5.2 — Array model used as a property (default)

Section titled “5.2 — Array model used as a property (default)”

When a property references an array model, it behaves the same as an inline array: the property name becomes the wrapper element and each item uses its type name as the element name.

model BookList is Book[];
model Book {
title: string;
}
model Store {
books: BookList;
}
<Store>
<books>
<Book>
<title>The Great Gatsby</title>
</Book>
<Book>
<title>Les Miserables</title>
</Book>
</books>
</Store>

@Xml.unwrapped on the property removes the wrapper element, just as with inline arrays.

model BookList is Book[];
model Book {
title: string;
}
model Store {
@Xml.unwrapped
books: BookList;
}
<Store>
<books>
<title>The Great Gatsby</title>
</books>
<books>
<title>Les Miserables</title>
</books>
</Store>

6.1 — Serializing a property as an XML attribute

Section titled “6.1 — Serializing a property as an XML attribute”

@Xml.attribute serializes a property as an XML attribute instead of a child element.

model Book {
@Xml.attribute
id: integer;
title: string;
author: string;
}
<Book id="0">
<title>The Great Gatsby</title>
<author>F. Scott Fitzgerald</author>
</Book>

@Xml.name or @encodedName on an @Xml.attribute property changes the attribute name in the XML output.

model Book {
@Xml.attribute
@Xml.name("xml-id")
id: integer;
title: string;
author: string;
}
<Book xml-id="0">
<title>The Great Gatsby</title>
<author>F. Scott Fitzgerald</author>
</Book>

@Xml.ns on a model adds a namespace prefix and declaration to the root element.

@Xml.ns("http://example.com/schema", "smp")
model Book {
id: integer;
title: string;
author: string;
}
<smp:Book xmlns:smp="http://example.com/schema">
<id>0</id>
<title>The Great Gatsby</title>
<author>F. Scott Fitzgerald</author>
</smp:Book>

7.2 — Namespace on individual properties

Section titled “7.2 — Namespace on individual properties”

Properties can declare their own namespace with @Xml.ns, which may differ from the model’s namespace.

@Xml.ns("http://example.com/schema", "smp")
model Book {
id: integer;
@Xml.ns("http://example.com/schema", "smp")
title: string;
@Xml.ns("http://example.com/ns2", "ns2")
author: string;
}
<smp:Book xmlns:smp="http://example.com/schema" xmlns:ns2="http://example.com/ns2">
<id>0</id>
<smp:title>The Great Gatsby</smp:title>
<ns2:author>F. Scott Fitzgerald</ns2:author>
</smp:Book>

Declare namespaces in an enum to avoid repeating URIs. Reference enum members with @Xml.ns.

@Xml.nsDeclarations
enum Namespaces {
smp: "http://example.com/schema",
}
@Xml.ns(Namespaces.smp)
model Book {
id: integer;
title: string;
author: string;
}
<smp:Book xmlns:smp="http://example.com/schema">
<id>0</id>
<title>Les Miserables</title>
<author>Victor Hugo</author>
</smp:Book>

Multiple namespace declarations can be defined in a single enum and referenced on individual properties.

@Xml.nsDeclarations
enum Namespaces {
smp: "http://example.com/schema",
ns2: "http://example.com/ns2",
}
@Xml.ns(Namespaces.smp)
model Book {
id: integer;
@Xml.ns(Namespaces.smp)
title: string;
@Xml.ns(Namespaces.ns2)
author: string;
}
<smp:Book xmlns:smp="http://example.com/schema" xmlns:ns2="http://example.com/ns2">
<id>0</id>
<smp:title>Les Miserables</smp:title>
<ns2:author>Victor Hugo</ns2:author>
</smp:Book>

@Xml.unwrapped on a scalar property makes it the text content of the parent element. Combined with @Xml.attribute, you can model elements that have both attributes and inline text.

model BookTitle {
@Xml.attribute language: string;
@Xml.unwrapped content: string;
}
<BookTitle language="en">
...content...
</BookTitle>