Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Yes—RAML 1.0 can describe XML request and response bodies. Add application/xml to the relevant body and use the RAML xml facet to control element names, attributes, collection wrappers, namespaces, and prefixes. The same logical API types can often serve JSON and XML, although XML-specific envelope types may be clearer when the wire formats differ.

This guide builds a complete jobs API and explains what RAML does—and does not—do at runtime.

RAML describes XML; it does not serialize your production API

RAML is a YAML-based API-description language. It defines HTTP resources, methods, types, media types, examples, and constraints for tools such as documentation generators, mock servers, validators, and code generators.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A RAML file alone does not change how an application produces or parses XML. Your framework, serializer, generated implementation, or gateway must support XML at runtime. Similarly, a mock server may generate a response from RAML, but that response reflects the mock tool’s implementation—not an automatic behavior of every RAML consumer.

RAML 1.0 is the relevant published specification. The public raml-spec repository was archived in February 2024, so check the documentation for the particular parser, mocking service, API console, or generator you use.

Start with a jobs API

Our example has a /jobs resource with GET and POST operations. A reusable logical model might begin like this:

#%RAML 1.0
title: Jobs API
version: v1
baseUri: https://api.example.com

mediaTypes:
  - application/json
  - application/xml

types:
  Location:
    type: object
    properties:
      city: string
      country: string

  Job:
    type: object
    properties:
      jobTitle: string
      company: string
      location?: Location
    example:
      jobTitle: API Developer
      company: Example Corp
      location:
        city: Austin
        country: USA

/jobs:
  get:
    responses:
      200:
        body:
          application/json:
            type: Job[]
          application/xml:
            type: Job[]
  post:
    body:
      application/json:
        type: Job
      application/xml:
        type: Job
    responses:
      201:
        body:
          application/json:
            type: Job
          application/xml:
            type: Job

A single media type can also be declared with mediaType: application/xml. For APIs supporting multiple formats, declaring each body explicitly makes the contract easier to read and avoids ambiguity in tools that expect media types at the operation level.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How the RAML xml facet works

RAML 1.0 defines XML serialization metadata on types and properties. The principal controls are name, attribute, wrapped, namespace, and prefix. Their meanings and restrictions are defined in the RAML 1.0 XML serialization section.

Rename elements without changing application properties

By default, a property’s XML name is derived from its RAML name. Use xml.name when the wire contract uses different capitalization or terminology:

types:
  Job:
    type: object
    xml:
      name: job
    properties:
      jobTitle:
        type: string
        xml:
          name: JobTitle
      company:
        type: string
        xml:
          name: Company
      location?: Location

The logical property remains jobTitle, while the XML element can be:

<JobTitle>API Developer</JobTitle>

instead of:

<jobTitle>API Developer</jobTitle>

This is useful when application code follows camelCase but an existing XML contract requires names such as JobTitle or COMPANY_NAME.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Rename the root element

Apply xml.name to the object type:

types:
  Job:
    type: object
    xml:
      name: jobs
    properties:
      jobTitle: string
      company: string

A serialized single instance may then use:

<jobs>
  <jobTitle>API Developer</jobTitle>
  <company>Example Corp</company>
</jobs>

The exact root for an array depends on the declared body shape and the selected processor. If the desired document has a collection envelope, model that envelope explicitly rather than assuming that naming the item type will create it.

Model nested objects and rename child elements

The reusable Location type can define its XML name:

types:
  Location:
    type: object
    xml:
      name: JobLocation
    properties:
      city: string
      country: string

  Job:
    type: object
    properties:
      jobTitle: string
      location?: Location

A representative result is:

<Job>
  <jobTitle>API Developer</jobTitle>
  <JobLocation>
    <city>Austin</city>
    <country>USA</country>
  </JobLocation>
</Job>

This is the intended shape, not a guarantee that every RAML mocker or serializer emits identical capitalization or placement. Inspect the output from your chosen implementation.

Map a scalar property to an XML attribute

Set attribute: true on a scalar property:

types:
  Job:
    type: object
    properties:
      jobTitle:
        type: string
        xml:
          attribute: true
          name: JobTitle
      company: string

The conceptual output becomes:

<Job JobTitle="API Developer">
  <company>Example Corp</company>
</Job>

RAML restricts XML attributes to scalar values. An object cannot be an attribute, and an array cannot normally be collapsed into one attribute. Attributes also cannot contain nested elements. On the wire, XML attribute values are text even when the logical RAML type is a number or Boolean; conversion and validation belong to the consuming tool or application. Attribute order is not semantically significant.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Arrays: wrapped and unwrapped collections

Collection shape is one of the easiest parts of an XML contract to get wrong. An unwrapped collection commonly appears as repeated item elements directly under its parent. A wrapped collection adds a containing element.

types:
  Job:
    type: object
    properties:
      title: string

  JobList:
    type: object
    properties:
      jobs:
        type: Job[]
        xml:
          wrapped: true
          name: jobs

The intended wrapped structure is:

<JobList>
  <jobs>
    <Job>
      <title>API Developer</title>
    </Job>
    <Job>
      <title>Platform Engineer</title>
    </Job>
  </jobs>
</JobList>

Without the wrapper, the items may instead be repeated directly:

<JobList>
  <Job>...</Job>
  <Job>...</Job>
</JobList>

wrapped creates an XML element around a type instance and cannot be applied to scalar types. Item naming can depend on the item type’s XML name and the processor’s rules. If interoperability matters, define names explicitly and test the actual serialized document.

Namespaces and prefixes

Standards-based XML often requires a namespace URI. RAML supports namespace and prefix:

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
types:
  Job:
    type: object
    xml:
      name: Job
      namespace: http://example.com/jobs
      prefix: j
    properties:
      jobTitle: string

A possible representation is:

<j:Job xmlns:j="http://example.com/jobs">
  <jobTitle>API Developer</jobTitle>
</j:Job>

The namespace URI identifies the XML vocabulary; the prefix is only a local shorthand. A serializer may declare the namespace on a different element or reuse a different prefix while remaining semantically equivalent. Validate namespace qualification with the receiving system.

Examples must match the declared media type

For an XML body, provide literal XML rather than a YAML object that merely represents the same data:

/jobs:
  get:
    responses:
      200:
        body:
          application/xml:
            type: JobList
            example: |
              <jobs>
                <job>
                  <JobTitle>API Developer</JobTitle>
                  <company>Example Corp</company>
                </job>
              </jobs>

The root name, capitalization, required fields, attributes, wrappers, and namespaces in the example must agree with the declared type and XML metadata. A JSON or YAML example is not automatically a valid XML example.

GET and POST: use the right HTTP headers

For a client requesting XML:

GET /jobs HTTP/1.1
Host: api.example.com
Accept: application/xml

For a client submitting XML:

POST /jobs HTTP/1.1
Host: api.example.com
Content-Type: application/xml
Accept: application/xml
  • Accept describes the response representation the client wants.
  • Content-Type describes the request body being sent.

An API may support XML responses but reject XML requests, or support JSON and XML independently. Declaring both in RAML documents the intended contract; it does not guarantee that the production server, gateway, or mock service implements both directions.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Supporting JSON and XML together

Shared logical types are appropriate when the representations contain essentially the same data:

types:
  Job:
    type: object
    properties:
      jobTitle: string
      company: string

/jobs:
  get:
    responses:
      200:
        body:
          application/json:
            type: Job[]
          application/xml:
            type: JobList

JSON arrays and XML documents often need different envelopes. In that case, reuse the common item type but create an XML-specific JobList wrapper. Do not force the two formats into identical structures when that makes either representation unnatural or incompatible with an established contract.

Testing workflow

  1. Start the file with #%RAML 1.0.
  2. Define the logical types and required properties.
  3. Add application/xml to each request or response body that supports XML.
  4. Use xml.name for non-default element or attribute names.
  5. Use xml.attribute: true only for scalar properties.
  6. Use xml.wrapped: true for collections that require an enclosing element.
  7. Add a literal XML example for every important XML shape.
  8. Validate the RAML with a RAML 1.0-compatible parser.
  9. Run a mock server or the real implementation and inspect the wire output.
  10. Test negotiation with both Accept and Content-Type.

MuleSoft tools can provide RAML design, documentation, and mocking workflows, but UI labels and feature availability vary by Anypoint edition and account. MuleSoft’s API specification documentation and API Mocking Service release notes are more reliable than screenshots from the original 2022 tutorial.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshooting XML RAML definitions

The XML body is not recognized

Check the media type spelling and location. Use conventional lowercase application/json and application/xml, and declare the body explicitly if the tool does not resolve global media types as expected.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The server returns JSON

Send Accept: application/xml, confirm that XML is implemented at runtime, and check whether the endpoint supports XML responses. RAML metadata cannot add a serializer to an existing server.

The root element is wrong

Check xml.name on the body type and whether the body is an item type or a collection. A collection may need a dedicated wrapper type such as JobList.

An attribute appears as an element

Confirm that attribute: true is nested under the scalar property’s xml node. If the property is an object or array, it cannot be represented as one attribute.

The array has the wrong shape

Decide whether the contract requires repeated items or a wrapper element. Set wrapped: true for the latter, configure item names where supported, and test with the selected processor.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The XML example fails validation

Compare the example with the type field by field. Look for a wrong root, case mismatch, missing required child, attribute supplied as an element, incorrect namespace, or a collection wrapper mismatch.

When an XSD is the better contract

RAML-native XML modeling is a good fit for straightforward REST payloads with elements, attributes, nested objects, collections, and alternate JSON/XML representations.

Prefer an established external XSD when the contract requires strict namespace qualification, mixed text and elements, substitution groups, advanced XSD constructs, or interoperability with systems that already validate against an industry schema. RAML can incorporate XML schemas, but schema-backed types have restrictions and cannot participate in RAML type inheritance or specialization in the same way as RAML-defined types.

Complete RAML 1.0 example

#%RAML 1.0
title: Jobs API
version: v1
baseUri: https://api.example.com
mediaTypes:
  - application/json
  - application/xml

types:
  Location:
    type: object
    xml:
      name: JobLocation
    properties:
      city: string
      country: string

  Job:
    type: object
    xml:
      name: job
    properties:
      jobTitle:
        type: string
        xml:
          name: JobTitle
          attribute: true
      company: string
      location?: Location

  JobList:
    type: object
    xml:
      name: jobs
    properties:
      jobs:
        type: Job[]
        xml:
          wrapped: true
          name: jobs

/jobs:
  get:
    responses:
      200:
        body:
          application/json:
            type: Job[]
          application/xml:
            type: JobList
            example: |
              <jobs>
                <jobs>
                  <job JobTitle="API Developer">
                    <company>Example Corp</company>
                    <JobLocation>
                      <city>Austin</city>
                      <country>USA</country>
                    </JobLocation>
                  </job>
                </jobs>
              </jobs>
  post:
    body:
      application/json:
        type: Job
      application/xml:
        type: Job
    responses:
      201:
        body:
          application/json:
            type: Job
          application/xml:
            type: Job

The double jobs structure in this deliberately explicit example reflects both the document type name and its wrapped collection property. If the target XML contract requires only one collection-level element, adjust the wrapper model and confirm the result with your processor. RAML’s model is the contract description; the final authority is the wire format accepted by the participating systems.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.