| // |
| // Copyright (c) 2020 Contributors to the Eclipse Foundation |
| // |
| |
| [appendix] |
| == External Binding Declaration |
| |
| === Example |
| |
| *_Example:_* Consider the following schema and external binding file: + |
| |
| Source Schema: `A.xsd`: |
| |
| [source,xml] |
| ---- |
| <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" |
| xmlns:ens="http://example.com/ns" |
| targetNamespace="http://example.com/ns"> |
| <xs:complexType name="aType"> |
| <xs:sequence> |
| <xs:element name="foo" type="xs:int"/> |
| </xs:sequence> |
| <xs:attribute name="bar" type="xs:int"/> |
| </xs:complexType> |
| <xs:element name="root" type="ens:aType"/> |
| </xs:schema> |
| ---- |
| |
| External binding declarations file: |
| |
| [source,xml] |
| ---- |
| <jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" |
| xmlns:xs="http://www.w3.org/2001/XMLSchema" |
| version="3.0"> |
| <jaxb:bindings schemaLocation="A.xsd"> |
| <jaxb:bindings node="//xs:complexType[@name=’aType’]"> |
| <jaxb:class name="customNameType"/> |
| <jaxb:bindings node=".//xs:element[@name=’foo’]"> |
| <jaxb:property name="customFoo"/> |
| </jaxb:bindings> |
| <jaxb:bindings node="./xs:attribute[@name=’bar’]"> |
| <jaxb:property name="customBar"/> |
| </jaxb:bindings> |
| </jaxb:bindings> |
| </jaxb:bindings> |
| </jaxb:bindings> |
| ---- |
| |
| Conceptually, the combination of the source |
| schema and external binding file above are the equivalent of the |
| following inline annotated schema. |
| |
| [source,xml] |
| ---- |
| <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" |
| xmlns:ens="http://example.com/ns" |
| targetNamespace="http://example.com/ns" |
| xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" |
| jaxb:version="3.0"> |
| <xs:complexType name="aType"> |
| <xs:annotation> |
| <xs:appinfo> |
| <jaxb:class name="customNameType"/> |
| </xs:appinfo> |
| </xs:annotation> |
| <xs:sequence> |
| <xs:element name="foo" type="xs:int"> |
| <xs:annotation> |
| <xs:appinfo> |
| <jaxb:property name="customFoo"/> |
| </xs:appinfo> |
| </xs:annotation> |
| </xs:element> |
| </xs:sequence> |
| <xs:attribute name="bar" type="xs:int"> |
| <xs:annotation> |
| <xs:appinfo> |
| <jaxb:property name="customBar"/> |
| </xs:appinfo> |
| </xs:annotation> |
| </xs:attribute> |
| </xs:complexType> |
| <xs:element name="root" type="ens:aType"/> |
| </xs:schema> |
| ---- |
| |
| === Transformation |
| |
| The intent of this section is to describe the |
| transformation of external binding declarations and their target schemas |
| into a set of schemas annotated with JAXB binding declarations. ready |
| for processing by a JAXB compliant schema compiler. |
| |
| This transformation must be understood to |
| work on XML data model level. Thus, this transformation is applicable |
| even for those schemas which contain semantic errors. |
| |
| The transformation is applied as follows: |
| |
| . Gather all the top-most `<jaxb:bindings>` |
| elements from all the schema documents and all the external binding |
| files that participate in this process. _Top-most_ `<jaxb:bindings>` are |
| those `<jaxb:bindings>` elements that are either a root element in a |
| document or whose parent is an `<xs:appinfo>` element. We will refer to |
| these trees as “external binding forest.” |
| . Collect all the namespaces used in the |
| elements inside the external binding forest, except the taxi namespace, |
| `"http://java.sun.com/xml/ns/jaxb"`, and the no namespace. Allocate an |
| unique prefix for each of them and declare the namespace binding at all |
| the root `<xs:schema>` elements of each schema documents. + |
| Then add a `jaxb:extensionBindingPrefix` attribute to each `<xs:schema>` |
| element with all those allocated prefixes. If an`<xs:schema>` element |
| already carries this attribute, prefixes are just appended to the |
| existing attributes. + |
| + |
| Note: The net effect is that all “foreign” namespaces used in the |
| external binding forest will be automatically be considered as extension |
| customization declaration namespaces. |
| . For each `<jaxb:bindings>` element, we |
| determine the “target element” that the binding declaration should be |
| associated with. This process proceeds in a top-down fashion as follows: |
| + |
| -- |
| .. Let `p` be the target element of the parent |
| `<jaxb:bindings>`. If it is the top most `<jaxb:bindings>`, then let |
| `p` be the `<jaxb:bindings>` element itself. |
| .. Identify the “target element” using `<jaxb:bindings>` attributes. |
| ... If the `<jaxb:bindings>` has a `@schemaLocation`, the value of the |
| attribute should be taken as an URI and be absolutized with the base URI |
| of the `<jaxb:bindings>` element. Then the target element will be the |
| root node of the schema document identified by the absolutized URI. If |
| there’s no such schema document in the current input, it is an error. |
| Note: the root node of the schema document is not the document element. |
| |
| ... If the `<jaxb:bindings>` has `@node`, |
| the value of the attribute should be evaluated as an XPath 1.0 |
| expression. The context node in this evaluation should be _p_ as we |
| computed in the previous step. It is an error if this evaluation results |
| in something other than a node set that contains exactly one element. |
| Then the target element will be this element. |
| |
| ... If the `<jaxb:bindings>` has neither |
| `@schemaLocation` nor `@node`, then the target element will be `p` as |
| we computed in the previous step. Note: `<jaxb:bindings>` elements can’t |
| have both `@schemaLocation` and `@node` at the same time. |
| -- |
| + |
| We define the target element of a binding |
| declaration to be the target element of its parent `<jaxb:bindings>` |
| element. The only exception to this is `<jaxb:globalBindings>` binding |
| declaraiton, in which case the target element will be the document |
| element of any one of the schema documents being compiled (such choice |
| is undeterministic, but the semantics of `<jaxb:globalBindings>` is not |
| affected by this choice, so the end result will be the same.) It is an |
| error if a target element of a binding declaration doesn’t belong to the |
| _"http://wwww.w3.org/2001/XMLSchema"_ namespace. |
| |
| . Next, for each target element of binding |
| declarations, if it doesn’t have any `<xs:annotation> <xs:appinfo>` in |
| its children, one will be created and added as the first child of the |
| target. |
| + |
| After that, we move each binding declaration under the target node of |
| its parent `<jaxb:bindings>`. Consider the first `<xs:appinfo>` child |
| of the target element. The binding declaration element will be moved |
| under this `<xs:appinfo>` element. |
| |