XML-encoded types
Object types that carry XML encoding metadata are generated as XML-capable models. Each one gets a serializer, a strict parser, and fluent builder methods for its child elements, so SDK users build and read XML documents (for example, telephony markup such as TwiML) through typed code instead of hand-written strings.
Fern generates XML support in TypeScript, Python, Java, C#, Go, Ruby, and PHP SDKs. No generators.yml configuration is required: generation is driven entirely by the XML metadata in your API definition. Types without XML metadata are unchanged, and the XML runtime is only added to an SDK when an XML-encoded type references it.
Define types with XML metadata
Fern reads the OpenAPI xml object on object schemas and their properties. name sets the element or attribute name, attribute: true emits a property as an XML attribute instead of a child element, and wrapped: true wraps an array in a container element. prefix and namespace are honored as well.
This definition describes documents like:
Element names, attributes, text bodies, nested and union children, repeated children, wrapped lists, list separators on attributes and text, namespaces, prefixes, and escaping are all honored.
Generated methods
Every XML-encoded type gets three capabilities, named idiomatically per language:
- Serialize:
toXml()(to_xmlin Python and Ruby,ToXml()in C# and Go) returns the element as an XML string. Root types (types never nested inside another XML type) include the<?xml version="1.0" encoding="UTF-8"?>declaration. - Parse:
fromXml(xml)(from_xmlin Python and Ruby,FromXml()in C#,<Type>FromXml()in Go) parses an XML string back into the model. Parsing is strict: it validates the root element name and scalar and enum values, and rejects malformed input andDOCTYPEdeclarations. - Build: one fluent method per child element type, named after the XML tag (for example,
garden.plant(...)). Each method constructs the child, appends it, and returns it so children can be chained. A child method gets anaddprefix (addPlant,add_plant,AddPlant) when its tag collides with a property or method of the parent, or when the name is a reserved word (addBreakin TypeScript,break_in Python and Ruby).
C#, Go, Ruby, and PHP also expose element-level variants (ToXElement()/FromXElement(), ToXmlElement()/<Type>FromXmlElement(), to_xml_element/from_xml_element, toXmlElement()/fromXmlElement()) for composing documents without re-parsing strings.
Round-tripping unknown content
Attributes and child elements that the schema doesn’t declare aren’t dropped. Parsing preserves them (additionalAttributes/additionalChildren in TypeScript, C#, Ruby, and PHP; ExtraAttributes/ExtraChildren in Go; getAdditionalChildren() in Java; extra attributes and XmlElement children in Python) and serialization re-emits them, so fromXml(model.toXml()) reproduces the original document. An addChild method (add_child in Python and Ruby, AddChild in C# and Go) appends an arbitrary element when building. Undeclared children are emitted after declared ones, so mixed-content ordering isn’t preserved.