Guide
Default encoding of scalars
Section titled “Default encoding of scalars”As in JSON, there is some default handling of the common scalars like utcDateTime:
| Scalar Type | Default Encoding | Encoding name |
|---|---|---|
utcDateTime | xs:dateTime | TypeSpec.Xml.Encoding.xmlDateTime |
offsetDateTime | xs:dateTime | TypeSpec.Xml.Encoding.xmlDateTime |
plainDate | xs:date | TypeSpec.Xml.Encoding.xmlDate |
plainTime | xs:time | TypeSpec.Xml.Encoding.xmlTime |
duration | xs:duration | TypeSpec.Xml.Encoding.xmlDuration |
bytes | xs:base64Binary | TypeSpec.Xml.Encoding.xmlBase64Binary |
1. Primitive properties
Section titled “1. Primitive properties”1.1 — Default serialization
Section titled “1.1 — Default serialization”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>Book: type: object properties: id: type: integer title: type: string author: type: string1.2 — Renaming a property
Section titled “1.2 — Renaming a property”@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;}model Book { id: integer;
@encodedName("application/xml", "book-title") title: string;
author: string;}<Book> <id>0</id> <book-title>The Great Gatsby</book-title> <author>F. Scott Fitzgerald</author></Book>Book: type: object properties: id: type: integer title: type: string xml: name: "book-title" author: type: string1.3 — Renaming the model
Section titled “1.3 — Renaming the model”@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;}@encodedName("application/xml", "XmlBook")model Book { id: integer; title: string; author: string;}<XmlBook> <id>0</id> <title>Les Miserables</title> <author>Victor Hugo</author></XmlBook>Book: type: object properties: id: type: integer title: type: string author: type: string xml: name: "XmlBook"2. Nested models
Section titled “2. Nested models”2.1 — Basic nested model
Section titled “2.1 — Basic nested model”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>Book: type: object properties: author: $ref: "#/components/schemas/Person"Person: type: object properties: name: type: string2.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;}model Book { author: Person;}
@encodedName("application/xml", "XmlPerson")model Person { name: string;}<Book> <author> <name>F. Scott Fitzgerald</name> </author></Book>Book: type: object properties: author: allOf: - $ref: "#/components/schemas/Person" xml: name: "author" # Here we have to redefine this name otherwise in OpenAPI semantic the `XmlPerson` name would be usedPerson: type: object properties: name: type: string xml: name: "XmlPerson"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;}model Book { @encodedName("application/xml", "xml-author") author: Person;}
model Person { name: string;}<Book> <xml-author> <name>F. Scott Fitzgerald</name> </xml-author></Book>Book: type: object properties: author: allOf: - $ref: "#/components/schemas/Person" xml: name: "xml-author"Person: type: object properties: name: type: string3. Array of primitive types
Section titled “3. Array of primitive types”3.1 — Wrapped primitive array (default)
Section titled “3.1 — Wrapped primitive array (default)”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>Book: type: "object" properties: tags: type: "array" xml: wrapped: true items: type: string xml: name: string3.2 — Unwrapped primitive array
Section titled “3.2 — Unwrapped primitive array”@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>Book: type: "object" properties: tags: type: "array" items: type: string xml: name: tags3.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[];}model Book { @encodedName("application/xml", "ItemsTags") tags: string[];}<Book> <ItemsTags> <string>fiction</string> <string>classic</string> </ItemsTags></Book>Book: type: "object" properties: tags: type: "array" xml: name: "ItemsTags" wrapped: true items: type: string xml: name: string3.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[];}model Book { @encodedName("application/xml", "tag") @Xml.unwrapped tags: string[];}<Book> <tag>fiction</tag> <tag>classic</tag></Book>Book: type: "object" properties: tags: type: "array" items: type: string xml: name: tag3.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[];}@encodedName("application/xml", "ItemName")scalar tag extends string;
model Book { @encodedName("application/xml", "ItemsTags") tags: tag[];}<Book> <ItemsTags> <ItemName>fiction</ItemName> <ItemName>classic</ItemName> </ItemsTags></Book>Book: type: "object" properties: tags: type: "array" xml: name: "ItemsTags" wrapped: true items: type: string xml: name: ItemName4. Array of complex types
Section titled “4. Array of complex types”4.1 — Wrapped array of models (default)
Section titled “4.1 — Wrapped array of models (default)”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>Book: type: "object" properties: title: type: "string"Store: type: "object" properties: books: type: "array" items: $ref: "#/components/schemas/Book" xml: wrapped: true4.2 — Unwrapped array of models
Section titled “4.2 — Unwrapped array of models”@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>Book: type: "object" properties: title: type: "string"Store: type: "object" properties: books: type: "array" items: $ref: "#/components/schemas/Book"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;}model Store { @encodedName("application/xml", "AllBooks") books: Book[];}
model Book { title: string;}<Store> <AllBooks> <Book> <title>The Great Gatsby</title> </Book> <Book> <title>Les Miserables</title> </Book> </AllBooks></Store>Book: type: "object" properties: title: type: "string"Store: type: "object" properties: books: type: "array" xml: name: "AllBooks" wrapped: true items: $ref: "#/components/schemas/Book"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;}model Store { @encodedName("application/xml", "BookItem") @Xml.unwrapped books: Book[];}
model Book { title: string;}<Store> <BookItem> <title>The Great Gatsby</title> </BookItem> <BookItem> <title>Les Miserables</title> </BookItem></Store>Book: type: "object" properties: title: type: "string"Store: type: "object" properties: books: type: "array" items: allOf: - $ref: "#/components/schemas/Book" xml: name: BookItem4.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;}model Store { @encodedName("application/xml", "AllBooks") books: Book[];}
@encodedName("application/xml", "BookItem")model Book { title: string;}<Store> <AllBooks> <BookItem> <title>The Great Gatsby</title> </BookItem> <BookItem> <title>Les Miserables</title> </BookItem> </AllBooks></Store>Book: type: "object" properties: title: type: "string" xml: name: "BookItem"Store: type: "object" properties: books: type: "array" xml: name: "AllBooks" wrapped: true items: allOf: - $ref: "#/components/schemas/Book" xml: name: BookItem5. Array models
Section titled “5. Array models”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[].
5.1 — Array model by itself
Section titled “5.1 — Array model by itself”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>Tags: type: "array" items: type: "string"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>Book: type: "object" properties: title: type: "string"BookList: type: "array" items: $ref: "#/components/schemas/Book"Store: type: "object" properties: books: type: "array" xml: wrapped: true items: allOf: - $ref: "#/components/schemas/Book" xml: name: "Book"5.3 — Unwrapped array model property
Section titled “5.3 — Unwrapped array model property”@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>Book: type: "object" properties: title: type: "string"BookList: type: "array" items: $ref: "#/components/schemas/Book"Store: type: "object" properties: books: type: "array" items: allOf: - $ref: "#/components/schemas/Book" xml: name: "books"6. Attributes
Section titled “6. Attributes”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>Book: type: object properties: id: type: integer xml: attribute: true title: type: string author: type: string6.2 — Renaming an XML attribute
Section titled “6.2 — Renaming an XML attribute”@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;}model Book { @Xml.attribute @encodedName("application/xml", "xml-id") id: integer;
title: string; author: string;}<Book xml-id="0"> <title>The Great Gatsby</title> <author>F. Scott Fitzgerald</author></Book>Book: type: object properties: id: type: integer xml: attribute: true name: "xml-id" title: type: string author: type: string7. Namespace and prefix (inline form)
Section titled “7. Namespace and prefix (inline form)”7.1 — Namespace on the model
Section titled “7.1 — Namespace on the model”@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>Book: type: object properties: id: type: integer title: type: string author: type: string xml: prefix: "smp" namespace: "http://example.com/schema"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>Book: type: object properties: id: type: integer title: type: string xml: prefix: "smp" namespace: "http://example.com/schema" author: type: string xml: prefix: "ns2" namespace: "http://example.com/ns2" xml: prefix: "smp" namespace: "http://example.com/schema"8. Namespace and prefix (normalized form)
Section titled “8. Namespace and prefix (normalized form)”8.1 — Using an @Xml.nsDeclarations enum
Section titled “8.1 — Using an @Xml.nsDeclarations enum”Declare namespaces in an enum to avoid repeating URIs. Reference enum members with @Xml.ns.
@Xml.nsDeclarationsenum 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>Book: type: object properties: id: type: integer title: type: string author: type: string xml: prefix: "smp" namespace: "http://example.com/schema"Namespaces: type: string enum: - http://example.com/schema8.2 — Multiple namespaces via enum
Section titled “8.2 — Multiple namespaces via enum”Multiple namespace declarations can be defined in a single enum and referenced on individual properties.
@Xml.nsDeclarationsenum 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>Book: type: object properties: id: type: integer title: type: string xml: prefix: "smp" namespace: "http://example.com/schema" author: type: string xml: prefix: "ns2" namespace: "http://example.com/ns2" xml: prefix: "smp" namespace: "http://example.com/schema"Namespaces: type: string enum: - http://example.com/schema - http://example.com/ns29. Property setting the text of the node
Section titled “9. Property setting the text of the node”9.1 — Text content with attributes
Section titled “9.1 — Text content with attributes”@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>BookTitle: type: object properties: language: type: string xml: attribute: true content: type: string