OpenAPI-Specification icon indicating copy to clipboard operation
OpenAPI-Specification copied to clipboard

How to represent XML elements with attributes

Open micovery opened this issue 8 years ago • 41 comments

Suppose I have the following XML:

<location>
  <coordinate format="lat-lon">a-b</coordinate>
</location>

I this the correct way to represent this using Swagger Schema objects?


---
  type: "object"
  xml: 
    name: "location"
  properties: 
    coordinate: 
      type: "string"
      properties: 
        format: 
          type: "string"
          xml: 
            attribute: true

It seems weird for the "coordinate" property ... which itself is of type "string" to contain a "properties" field. Coming from JSON-Schema-Draft-V4 background, you would not expect a "string" field to have properties, because there is no such thing in JSON.

But then again, this is a "Swagger Schema Object" ... not a JSON-Schema-Draft-V4. I just want confirmation whether or not this is the correct way to do it.

micovery avatar Apr 07 '16 21:04 micovery

When it comes to pure json schema, that's actually not illegal, but the properties, when it comes to json, would be effectively ignored.

As for the answer to your actual question - there's pretty much no way to represent that currently with 2.0. The attributes can pretty much be applied only to objects.

webron avatar Apr 07 '16 23:04 webron

Nice idea.

I guess Swagger/OpenAPI can not describe many types of XML, just those that have an obvious 1:1 mapping to JSON which can be described by OpenAPI itself. As there is no JSON equivalent to your XML fragment, it can't be described with Swagger either.

ePaul avatar Apr 08 '16 17:04 ePaul

Thanks @webron and @ePaul for the clarifications.

That's correct, my sample XML has no way of being represented as JSON ... unless you adopt some convention like BadgerFish (http://www.sklar.com/badgerfish/)

where it would be represented like this:

{
  "location": {
    "coordinate": {
      "@format": "lat-lon",
      "$": "a-b",
    }
  }
}

(which itself could be described purely by JSON Schema without resorting to using the xml field that Swagger came up with).

But, putting that aside ... since it's not illegal (as @webron pointed out) in JSON-Schema-Draft-V4 for a string to have properties ... OpenAPI could accept it as a valid schema to describe XML ... just a matter of convention.

micovery avatar Apr 09 '16 08:04 micovery

This is primarily a problem when you are trying to use swagger to document an already existing API (that is, an API that you can't change). Which is a pretty big bummer!

eminence avatar May 12 '16 18:05 eminence

This could be solved by adding the convention to OpenAPI 3.0 that the text node of an XML element is represented as a property whose name is the empty string:

  type: "object"
  xml: 
    name: "location"
  properties: 
    coordinate: 
      type: "object"
      properties: 
        format: 
          type: "string"
          xml: 
            attribute: true 
        "": 
          type: "string"

ralfhandl avatar Oct 10 '16 08:10 ralfhandl

Oh man! If that's the type of hacking we can expect in this spec for 3.0, then I'd consider it a failure. A property whose name is an empty string? Really? That's intentional / by design? I can hear the death knell for Swagger now!

AlskiOnTheWeb avatar Mar 20 '17 11:03 AlskiOnTheWeb

Any reserved property name that cannot be mistaken for an XML attribute name would do the trick, the empty name is just the shortest possible choice. Another obvious name would be text() - also no risk of clashing with an XML attribute name in someone's API out there.

ralfhandl avatar May 18 '17 12:05 ralfhandl

Ugh. The hacking shows the lack for forethought that went into this stuff. If Swagger / OpenAPI were designed from the get go to be suitably generic, these hacks wouldn't be needed. It's like the nasty "discriminator" hack to make things look hierarchical through some messed up definition. It's no wonder adoption for existing APIs is so low for this stuff....

AlskiOnTheWeb avatar May 18 '17 13:05 AlskiOnTheWeb

I assume Swagger / OpenAPI was primarily invented for describing APIs that use the JSON format, and I think it does a great job in that area.

Unfortunately its JSON-Schema-based payload description syntax only supports a subset of XML, and the most prominent gap is XML elements with text content.

@AlskiOnTheWeb how would you address this gap?

ralfhandl avatar May 18 '17 15:05 ralfhandl

I have seen many javascript webpages use _ prefix in json to denote an attribute and __ prefix to denote inner text. Also I found this on the web http://wiki.open311.org/JSON_and_XML_Conversion/

dskow avatar Jul 28 '17 13:07 dskow

As we have the attribute property on the xml object already, perhaps it makes sense to add a text property (also of type boolean) to indicate that the property represents the xml text node, where at most only one property of an object SHOULD be marked text: true?

Thus

location:
  type: "object"
  properties: 
    coordinate: 
      type: "object"
      properties: 
        format: 
          type: "string"
          xml: 
            attribute: true 
        value: 
          type: "string"
          xml:
            text: true

would represent the xml

<location>
  <coordinate format="lat-lon">a-b</coordinate>
</location>

MikeRalphson avatar Dec 11 '17 10:12 MikeRalphson

I inadvertantly added another bug here: #2624

I would also like to suggest a similar solution as @MikeRalphson, with 1 possible tweek:

  TypeName:
    type: "object"
    properties:
      href:
        type: "string"
        example: "example.com"
        xml:
          attribute: true
      value:
        type: "string"
        example: "SampleTypeName"
        xml:
          wrapped: "false"
    xml:
      name: "typeName"

Which would produce:

<typeName href="example.com">SampleTypeName</typeName>

Like wise, we're also using the (http://www.sklar.com/badgerfish/) convention for converting to json objects, per @micovery comment above.

ronniedepriest avatar Jan 17 '18 16:01 ronniedepriest

Hi With MikeRalphson and ronniedepriest‘s comments, I just got something like this: I could not remove the value tag, is there any good ideas? <typeName href="example.com"> <value>SampleTypeName</value> </typeName>

andygaga2018 avatar May 22 '18 03:05 andygaga2018

@andygaga2018 to make things clear, both of the examples above are proposals for future versions of the OpenAPI Specification. They won't work today in any existing tools.

MikeRalphson avatar May 22 '18 09:05 MikeRalphson

Not sure if that made things completely clear. Let me add: the xml/attribute flag is available in OpenAPI Spec 3.0.0.

This schema:

components:
  schemas:
    Person:
      type: object
      xml:
        namespace: http://example.com/schema/sample
      properties:
        id:
          type: integer
          format: int32
          xml:
            attribute: true
        name:
          type: string
          xml:
            namespace: http://example.com/schema/sample
      required:
        - name
        - id

allows this XML

<Person xmlns="http://example.com/schema/sample" id="0">
	<name>string</name>
</Person>

DinoChiesa avatar Jun 13 '18 15:06 DinoChiesa

I stumbled upon this issue today. I guess the problem is not with the attributes - they work fine, the problem is with objects that have both attributes and a value. Maybe the title of the issue could be rephrased to indicate that?

Solution wise.. I'm +1 on text: true or inline: true.

How should we move this forward?

dinamic avatar Dec 05 '18 12:12 dinamic

Describing non-object elements with attributes such as <coordinate format="lat-lon">a-b</coordinate> will be possible with x-oas-draft-alternativeSchema (#1532) if that proposal is implemented.

hkosova avatar Jan 14 '19 09:01 hkosova

How to represent below xml in swagger 2.0? <CID name="ClientId"> 123 </CID>

deepthisharmaBKFS avatar Feb 01 '19 14:02 deepthisharmaBKFS

has this issue been resolved ?? I don't see any mention of it in 3.0.2 release notes

anandsunderraman avatar Mar 15 '19 13:03 anandsunderraman

The issue is still open / unresolved. As per our development guide, it isn't the kind of thing which can be changed in a patch release.

MikeRalphson avatar Mar 15 '19 15:03 MikeRalphson

This worked for me:

"geolocation": { "type": "object", "title": "geolocation", "properties": { "coordinates": { "name": "coordinates", "$ref": "./coordinates.json" } } }

And this is the contents of the referenced file:

{ "type": "object", "title": "coordinates", "required": [ "latitude", "longitude" ], "properties": { "latitude": { "type": "number", "format": "float" }, "longitude": { "type": "number", "format": "float" } } }

amandajordaan avatar May 06 '19 07:05 amandajordaan

Is this going to be addressed in future OpenAPI specifications? eg 3.1 or 4.0?

rLitto avatar Oct 29 '20 16:10 rLitto

With 3.1 being almost ready, it's unlikely to make it in. Based on work that has been done the last couple of years, I suspect it's more likely we'll see support for other schemas (such as XSD) rather than trying to resolve this issue, but time will tell.

webron avatar Nov 02 '20 21:11 webron

It's sad to see how an issue has been neglected for 4 years and counting. :(

dinamic avatar Nov 03 '20 09:11 dinamic

4 years and counting for sure...and it won't end either since the spec itself is fundamentally flawed. The hens have come to roost for this problem, what went around came around. Poor design / poor result. Garbage in / Garbage out.

AlskiOnTheWeb avatar Nov 03 '20 12:11 AlskiOnTheWeb

Based on work that has been done the last couple of years, I suspect it's more likely we'll see support for other schemas (such as XSD)

That helps in the sense that we have well documented XSDs already. In JSON Schema I'm missing mixed node support, enum content description support, support for <xs:attributeGroup ref="..."/>, support for $ref + a tweak, like deprecating the calling property or supplying a new default (cannot use anything next to $ref according to the validators), and then some like comment().

The downside is having to maintain 2 schemas. The notion of one schema to rule them all was fun while it lasted I guess.

ahenket avatar Jan 14 '21 07:01 ahenket

Just a note that JSON Schema draft 2020-12 (which will be referenced by OAS 3.1) does support some of these constructs, such as $ref with siblings and $comment. enums with descriptions can also be expressed as oneOfs with consts in each branch - though tooling will have to recognise that pattern as equivalent to an enum.

Depending on the appetite for alternative-schema support, there could be room for xmlObject improvements in OAS 3.2.

MikeRalphson avatar Jan 14 '21 08:01 MikeRalphson

I found this thread while trying to figure out how to add an XML attribute to what would be an array in the JSON definition. e.g. something like the count attribute here:

<nodes count="1">
	<node id="3fa85f64-5717-4562-b3fc-2c963f66afa6">
        ...stuff...
	</node>
</nodes>

It does not look like that is currently possible, so i wanted to make sure this use-case is also on your radar.

bdunavant avatar May 24 '21 21:05 bdunavant

Stuck with this issue too!

oderayi avatar Jun 04 '21 11:06 oderayi

Is there any workaround to do it in dot net core ISchemaFilter. Inner text example value not showing in swager openAPI schema.

<periodStart>2021-08-06T17:06:29.918</periodStart> <periodStop>2021-08-06T17:06:29.918</periodStop> **<totalQuantity unit="Mwh"> </totalQuantity>**

if (property.Key == "totalQuantity") { schema.Properties[property.Key].Type = "string";

  schema.Properties[property.Key].Xml = new OpenApiXml() { Wrapped =false, Attribute = false, Name = ""};
                   
  schema.Properties[property.Key].Example = new Microsoft.OpenApi.Any.OpenApiString("25.0");

}

padhumailin avatar Aug 06 '21 11:08 padhumailin