Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xml example cannot be generated for response type of array #4650

Open
borcherspm opened this issue Jun 15, 2018 · 37 comments
Open

xml example cannot be generated for response type of array #4650

borcherspm opened this issue Jun 15, 2018 · 37 comments

Comments

@borcherspm
Copy link

Q&A (please complete the following information)

  • OS: Windows 10
  • Browser: Firefox, Chrome, Edge
  • Method of installation: npm
  • Swagger-UI version: 3.11.0
  • Swagger/OpenAPI version: Swagger 2.0

Content & configuration

I've reproduced this locally, but even easier to demonstrate, petstore has the same issue.

Example Swagger/OpenAPI definition:
https://generator.swagger.io/api/swagger.json

snippet from swagger.json

      responses:
        200:
          description: "successful operation"
          schema:
            type: "array"
            items:
              $ref: "#/definitions/Pet"

Describe the bug you're encountering

In swagger ui, when you have a GET that has a response that is a list, and you selected content type of xml, the Example Value has an error "XML example cannot be generated".

To reproduce...

Steps to reproduce the behavior:

  1. Go to https://editor.swagger.io
  2. Expand /pet/findByStatus
  3. Make sure Response content type is application/xml
  4. Example Value for status code 200 has "XML example cannot be generated"

Expected behavior

I would expect to see the example xml for the response.

Screenshots

image

@Mic75
Copy link

Mic75 commented Mar 11, 2019

Hello @shockey , any ETA on a fix regarding this issue?

@euroform-pa
Copy link

@shockey We're facing issue with XML sample generation in case of collection is part of response object. Kindly let us know about ETA on a fix.

@euroform-pa
Copy link

Added the demo project to reproduce the issue with Swashbuckle for Xml sample generation issue. Demo project
Kindly suggest the solution to view correct Xml sample generation.

@euroform-pa
Copy link

Added the demo project to reproduce the issue with Swashbuckle for Xml sample generation issue. Demo project
Kindly suggest the solution to view correct Xml sample generation.

Any update on this?

@wambling
Copy link

Any workaround solution for this?

@NickNiebling
Copy link

I think this might be related to older issue:
XML Example for Arrays does not display #3132

Above issue does speak to at least some issue with Swashbuckle OpenAPI generation:

Yes we are but its an issue with Swashbuckle not generating the appropriate swagger doc info; once i add that information in, the UI renders fine ... the Petstore example is also broken in the same way and needs to be amended to include the xml.name/wrapped elements

Re. workaround, there is more information in above issue:

I just realized a single-item example is actually correct. To have array items wrapped into an extra tag, the array schema must have xml.wrapped=true.

Another issue ´seems to be related as well:
XML example cannot be generated with 'allOf' #4423

This has been an issue for a while, but apparently not a priority to fix (I assume collaborators are all using json or don't mind too much about XML examples).

@ghost
Copy link

ghost commented Nov 13, 2019

I'm using NuGet Package Swashbuckle.AspNetCore 5.0.0-rc4 and this is still an Issue on November 12, 2019

@ghost
Copy link

ghost commented Nov 13, 2019

When you generate the schema for response type 200 for app/ToDoItems/1 we get the following schema for responses:

"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TodoItem"
}
},
"application/xml": {
"schema": {
"$ref": "#/components/schemas/TodoItem"
}
}
}
},

When you generate the schema for response type 200 for app/ToDoItems we get the following schema for responses:

"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/TodoItem"
}
}
},
"application/xml": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/TodoItem"
}
}
}
}
},

Its this second scenario that is producing the error "XML example cannot be generated; root element name is undefined" in the Swagger UI.

@calife
Copy link

calife commented Jan 29, 2020

You can use something like this to wrap

    responses:
      '200':
        description: Success
        content:
        
          'application/xml':
            schema:
              type: array
              items:
                $ref: '#/components/schemas/SDDLItem'
              xml:
                name: response

components:
schemas:

SDDLItem:
  type: object
  xml:
    name: SDDLItem  

@whateverxforever
Copy link

Did anyone figure out a workaround for this issue or does this issue still exist?

@whateverxforever
Copy link

You can use something like this to wrap

    responses:
      '200':
        description: Success
        content:
        
          'application/xml':
            schema:
              type: array
              items:
                $ref: '#/components/schemas/SDDLItem'
              xml:
                name: response

components:
schemas:

SDDLItem:
  type: object
  xml:
    name: SDDLItem  

This is not working due to some reason.

@fdcds
Copy link

fdcds commented Apr 8, 2020

Did anyone figure out a workaround for this issue or does this issue still exist?

Providing any schema: xml: name: ... did the trick for me. The value is ignored (because schema: xml: wrapped: true is not set), but at least the example is rendered fine.

@Sslimon
Copy link

Sslimon commented Jun 8, 2020

Hi all

Are there some updates about this? I think I have a similar problem:

I have a Spring Boot Rest Api and I want to have the swagger documentation. Mostly the Api produces application/xml. When the return class is annotated with XmlRootElement and the properties have the XmlElement attributes everything is working fine. But if a primitive type or a List is returned, the root element is missing. Is it somehow possible to tell springdoc he should use jaxb to generate all this information/names. So that the xml has the root name and everything which then really gets returned?

Thank you very much and best
Simon

@whateverxforever
Copy link

whateverxforever commented Jun 8, 2020

I found a work-around for this
https://app.swaggerhub.com/apis/whateverxforever/SampleApi/v1-oas3

 get:
      summary: List of all orders
      operationId: getOrderList
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Order'
            application/xml:
              schema:
                type: object
                xml:
                  name: Data
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Order'

I hope this helped! 😉

@Sslimon
Copy link

Sslimon commented Jun 8, 2020

@whateverxforever Thanks for you response :)

This would work, yes. But I use springdoc openapi which generates the swagger json file for me. When I annotate my models with @XmlRootElement and @xmlelement the generated schema: xml: is written correctly.

For example like this:

@XmlRootElement
public class Employee {
    @XmlElement
    private Address address;
}

@XmlRootElement
public class Address {
}

But if the return type of an endpoint is a primitive data type like boolean or a List than the schema: xml: is completely missing.

I could add them manually, but the project is quite big.
Or I could write wrapper classes, but I should not change the code.

My idea then was if swagger could use jaxb to create this xml informations. Like this, the xml names would be exactly the same as the rest endpoint returns.

Do you know more or less what i mean :)

@whateverxforever
Copy link

Hello @Sslimon,

I faced the same issue while generating docs using Stoplight for my project. Stoplight was generating the doc fine for JSON data but for XML I had to manually go at each end point and write the code myself. I know it's not what you wanted to hear 😓, but I think this is a common issue in swagger. Sorry couldn't be of any more help.

@Sslimon
Copy link

Sslimon commented Jun 8, 2020

Okay, too bad. I was hoping that somebody maybe knows a workaround, but then I can't avoid to adapt it myself :) The JSON is also correct, only the xml stuff is sometime wrong/not complete. But thank you very much for your answers and help!

@arivera12
Copy link

I just hit this bug and wow almost 3 years and no fix...

@MDerrickGlass
Copy link

Same here - Using Swashbuckle 6.1.4 for .NET 5.0.7; I guess no one cares about XML anymore? :)

@bluish5
Copy link

bluish5 commented Jul 23, 2021

Oh my god... I worked many hours for setting up integration between Maven, Jersey, Swagger, Swagger UI... for documenting my WS and now I discover that there is such a big blocking bug, open since 3 years???
I ask for Swagger developers intervention and for workaround suggestions from peers. Thanks

@bluish5
Copy link

bluish5 commented Jul 23, 2021

At least someone understood if the problem is in the swagger.json generated by Swagger Core or in the way that Swagger UI interprets it? Just to find where we could try to create a workaround in the meanwhile... Thanks

@bluish5
Copy link

bluish5 commented Jul 23, 2021

Thanks to these posts:

I solved the problem with this workaround, waiting for the bug to be solved:

  • i take the generated swagger.json
  • i format it with Notepad++ and its JSON plugin
  • wherever I find a block like this:
"type": "array",
"items": {
	"$ref": "#/definitions/MyObject"
}

I replace it with a block like this:

"type": "object",
"xml": {
	"name": "MyObjects"
},
"properties": [
	{
		"type": "array",
		"items": {
			"$ref": "#/definitions/MyObject"
		}
	}
]
  • I save the new file in a webapp folder and use its URL in Swagger UI for rendering docs

@ppazos
Copy link

ppazos commented Nov 25, 2021

The issue doesn't seem to have a workaround when the XML is just one element with a text node.

The goal is <token>xxxx</token> but I got

<token>
	<token>string</token>
</token>
            application/xml:
              schema:
                type: object
                xml:
                  name: token
                properties:
                  token:
                    type: string

@JeroenHeemskerk
Copy link

JeroenHeemskerk commented Jan 21, 2022

I found out that if you include an xml name AND wrapped: true it wil generate a correct xml example, and even arrays of string can be controlled how the xml examle is shown for the element tag.

For example in the Pet example code if you add these 3 lines to the response code and/or these 2 lines to the items section in de definitions:

responses:
        "200":
          description: "successful operation"
          schema:
            type: "array"
            xml:             # <<
              name: "Pets"   # << root tag name
              wrapped: true  # << mandatory
            items:
              $ref: "#/definitions/Pet"
...
definitions:
  Pet:
    type: "object"
    required:
    - "name"
    - "photoUrls"
    properties:
      id:
        type: "integer"
        format: "int64"
        xml:
          attribute: true
      category:
        $ref: "#/definitions/Category"
      name:
        type: "string"
        example: "doggie"
      photoUrls:
        type: "array"
        xml:
          name: "PhotoUrls"
          wrapped: true
        items:
          xml:                # <<
            name: "PhotoUrl"  # <<  
          type: "string"
          example: "(uuencoded string)"
      tags:
        type: "array"
        xml:
          name: "Tags"
          wrapped: true
        items:
          $ref: "#/definitions/Tag"
      status:
        type: "string"
        description: "pet status in the store"
        enum:
        - "available"
        - "pending"
        - "sold"
    xml:
      name: "Pet"

it wil correctly make an example with a root tag :

<?xml version="1.0" encoding="UTF-8"?>
<Pets>
	<Pet id="0">
		<Category id="0">
			<name>shepherd</name>
		</Category>
		<name>doggie</name>
		<PhotoUrls>
			<PhotoUrl>(uuencoded string)</PhotoUrl>
		</PhotoUrls>
		<Tags>
			<Tag id="0">
				<name>playfull</name>
			</Tag>
		</Tags>
		<status>available</status>
	</Pet>
</Pets>

@bluish5
Copy link

bluish5 commented Feb 15, 2022

Thank you @JeroenHeemskerk, your workaround works and is simpler than mine!
For my own reference I report it in JSON format.
When Swagger writes a block like this:

"200": {
    "description": "successful operation",
    "schema": {
        "type": "array",
        "items": {
            "$ref": "#/definitions/MyObject"
        }
    }
},

we can correct it inserting this block:

"xml": {
    "name": "MyObjects",
    "wrapped": "true"
},

and obtaining this:

"200": {
    "description": "successful operation",
    "schema": {
        "type": "array",
        "xml": {
            "name": "MyObjects",
            "wrapped": "true"
        },
        "items": {
            "$ref": "#/definitions/MyObject"
        }
    }
},

@Aravinda93
Copy link

@bluish5 Thanks for this. I am getting a similar issue when I am using the Swagger-ui with Java OpenAPI and I am not understanding where to add the wrapped:true in this:

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.Map;

@Path("/api")
public class RestControllerResponse {

    @Path("/generate")
    @POST
    @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
    @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
    public String generator(final Map<String, Object> input) throws Exception {
        return "Hello From Generator Method";
    }
}

Please let me know where to add.

@JeroenHeemskerk
Copy link

@Aravinda93, I do not understand your question. The workaround I described is for yaml or json file.
Are you generating swagger files from a RestController or do you have a swagger yaml or json file as well?

@Aravinda93
Copy link

@JeroenHeemskerk I am developing a RestController application using the Quarkus. Within this, I am using the OpenAPI to add the annotations to my method. This functionality can be tested on the Swagger-UI.

When the application gets started the openapi.yaml is created automatically based on the OpenAPI annotations. In my Swagger-UI I am getting the error XML example cannot be generated; root element name is undefined.

I am not creating the yaml files myself so I wanted to know where can I add the wrapped:true in my Annotations so as to fix this issue.

Ref document: https://quarkus.io/guides/openapi-swaggerui

@bluish5
Copy link

bluish5 commented Apr 27, 2022

Hi @Aravinda93, my solution is to edit the generated YAML (or JSON in my case) file, after it has been generated. You save it with a different file name and when user opens Swagger-UI you feed it with your edited file instead of the generated one.
Obviously, from now on, whenever your introduce changes in your API annotations (e.g. when you create a new WS method), you must keep your edited version up-to-date.
Hope it's all clear ;)

@JeroenHeemskerk
Copy link

@borcherspm, I see the XML attribute it is added to the 3.0.0 spec https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md#xml-attribute-prefix-and-namespace but i do not see an annotation for it in the swagger-ui in the https://github.com/eclipse/microprofile-open-api/wiki/Annotation-Samples nor in the code on GitHub. I am affraid there is no annotation for it build yet.

There may be a workaround if you make a OASFilter: https://github.com/eclipse/microprofile-open-api/wiki/OASFilter-Samples using a "filterSchema".
Something like the pseudocode below (warning untested code block)

@Override
Schema filterSchema(Schema schema) {
  if ( /* test if this is the corrrect definition/response */ ) {
     schema.SetXml(new Xml().name("myObjects").wrapped(true));
  }
  return schema;
}

@JeroenHeemskerk
Copy link

I made an issue for it microprofile/microprofile-open-api#530

@Aravinda93
Copy link

@JeroenHeemskerk Thanks a lot for taking the initiative to find the issue and create the issue.

I am looking at your provided workaround and trying to achieve something like this. Since it is untested I am getting a few issues.

I have created the custom OASFilter and added the same to my project and trying to do something like what you are doing but I am unable to follow certain things. Can you please help me in figuring out the issue? I am unable to follow what exactly I need to check in IF condition and return the schema.

Following is the OASFilter that I have created and added the same to my application.properties file in the Quarkus application:

package org.acme;

import org.eclipse.microprofile.openapi.OASFilter;
import org.eclipse.microprofile.openapi.annotations.media.Schema;

public class TestSchema implements OASFilter {
    
    @Override
    Schema filterSchema(Schema schema) {
        if ( /* test if this is the corrrect definition/response */ ) {
            schema.SetXml(new Xml().name("myObjects").wrapped(true));
        }
        return schema;
    }
}

@JeroenHeemskerk
Copy link

@Aravinda93 someone made the suggestion to use @XmlElementWrapper(name="myobjects") en @XmlElement(name="myObject"), maybe that will do the trick?

@arivera12
Copy link

4 year as past since today and still no fix?

Whats up with this project it's dead or what?

@rishitank
Copy link

It's 2023, the pandemic is over but this bug is not? 🤔

@Absolemus
Copy link

I was here, and I came here to see if the bug was fixed. 2024 BC

@rishitank
Copy link

This may have been fixed in ReDoc: Redocly/redoc#2347

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests