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. Attributes
Section titled “5. Attributes”5.1 — Serializing a property as an XML attribute
Section titled “5.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: string5.2 — Renaming an XML attribute
Section titled “5.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: string6. Namespace and prefix (inline form)
Section titled “6. Namespace and prefix (inline form)”6.1 — Namespace on the model
Section titled “6.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"6.2 — Namespace on individual properties
Section titled “6.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"7. Namespace and prefix (normalized form)
Section titled “7. Namespace and prefix (normalized form)”7.1 — Using an @Xml.nsDeclarations enum
Section titled “7.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/schema7.2 — Multiple namespaces via enum
Section titled “7.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/ns28. Property setting the text of the node
Section titled “8. Property setting the text of the node”8.1 — Text content with attributes
Section titled “8.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