-
Notifications
You must be signed in to change notification settings - Fork 9.1k
v3.2: Support all common XML node types (element, attribute, text, cdata) #4592
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
base: v3.2-dev
Are you sure you want to change the base?
Conversation
Clarifies that the name of the root XML element comes from the component name, which was shown in an example but was unclear due to the use of the obsolete OAS 2.0 terminology "model." This does not change the restriction (in the `xml` field of the Schema Object) that the `xml` field only applies to property schemas (and not root schemas).
This avoids reinforcing the "root schema" vs "property schema" restriction that we plan to relax.
This change adds a nodeType field to support the four most commonly used XML node types: element, attribute, text, and cdata. A fifth nodetype, none, is used to prevent a Schema Object from producing a node. This also removes the restriction on where the xml field and XML Object can appear, as the nodeType system is more flexible than the old system. This deprecates two existing fields: * attribute, replaced by nodeType: attribute * wrapped, replaced by nodeType: none
|
||
##### Fixed Fields | ||
|
||
| Field Name | Type | Description | | ||
| ---- | :----: | ---- | | ||
| <a name="xml-name"></a>name | `string` | Replaces the name of the element/attribute used for the described schema property. When defined within `items`, it will affect the name of the individual XML elements within the list. When defined alongside `type` being `"array"` (outside the `items`), it will affect the wrapping element if and only if `wrapped` is `true`. If `wrapped` is `false`, it will be ignored. | | ||
| <a name="xml-node-type"></a>nodeType | `string` | One of `element`, `attribute`, `text`, `cdata`, or `none`, as explained under [XML Node Types](#xml-node-types). The default value is `none` if `$ref`, `$dynamicRef`, or `type: "array"` is present in the [Schema Object](#schema-object) containing the XML Object, and `element` otherwise. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not 100% the bits about $ref
and $dynamicRef
are backwards-compatible, because I'm not sure what, if anything, the behavior was in those cases before, as "property schema" was not well-defined. If we mean "literal inline schema directly under a name under properties
without references", then there was no defined behavior and we can do what we want.
Otherwise, it might not be, and we should let schemas containing $ref
or $dynamicRef
have a default nodeType
of element
, and folks can explicitly set them to none
. I don't think that change would impact anything else in this PR, and might be the more conservative compatibility choice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed up to "XML Object Examples"
| <a name="xml-wrapped"></a>wrapped | `boolean` | MAY be used only for an array definition. Signifies whether the array is wrapped (for example, `<books><book/><book/></books>`) or unwrapped (`<book/><book/>`). Default value is `false`. The definition takes effect only when defined alongside `type` being `"array"` (outside the `items`). If `nodeType` is present, this field MUST NOT be present.<br /><br />**Deprecated:** Set `nodeType: "element"` explicitly in place of `wrapped: true` | | ||
|
||
Note that when generating an XML document from object data, the order of the nodes is undefined. | ||
Use `prefixItems` to control node ordering. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How would that work? Given that document order is significant in XML, an example would be helpful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ralfhandl there is an example... didn't you say you hadn't read the examples section yet? ;-)
In all seriousness, I'd love better examples once you get there, I struggle to come up with them. But there is a prefixItems
example.
Co-authored-by: Ralf Handl <[email protected]>
null
values)This change removes the restriction on where the
xml
field and XML Object can appear, and adds anodeType
field to support the four most commonly used XML node types:element
,attribute
,text
, andcdata
. A fifth nodetype,none
, is used to prevent a Schema Object from producing a node.It also adds many examples of how to model different XML scenarios, including using
prefixItems
for complex ordered nodes.While this could have been made much simpler by always defaulting
nodeType
toelement
, a more complex requirement was needed to preserve compatibility with the existing (but now deprecated - see also PR #4591)attribute
andwrapped
fields. This way, the behavior of an XML object that is empty or uses onlyname
,prefix
, and/ornamespace
behaves the same whether you look at defaults fornodeType
or forattribute
andwrapped
.I expect the deprecation of
attribute
andwrapped
to be controversial, but there are several reasons for doing it:text
, to indicate text nodes. But if we are going to support text nodes, we definitely also want to support CDATA sections, which would require three fields (attribute
,text
, andcdata
) that were all mutually exclusive. One boolean is fine, but three to manage a single state is more design smell than I can handle.wrapped
field is a very specific case of a more general problem, which is Schema Objects that do not correspond to XML nodes. The old wording only acknowledged "property" and "root" schemas, and ignored the many other sorts of Schema Objects that might appear, and the complex ways in which they might map (or not) to XML nodes. ThenodeType: none
construct allows controlling this in a generalized way.name
behavior, as certain types have names and others do not. This is much more intuitive than logic involvingwrapped
.null
-handling problems in Formalize how to express null value in xml #3959 are tricky, and this allows us to (if we want) define clear behavior fornodeType: attribute
without breaking existing support forattribute: true
.In addition to
null
handling, I came up with several other possible caveats to call out or clarify, but I wanted to keep this as minimal as possible. If the related concerns come up in review I can add them, otherwise I will do it as a follow-on if it seems useful. But let's see how this lands first.