This XSD portion was obtained from: http://www.iana.org/assignments/xml-registry/schema/netconf.xsd
<xs:complexType name="rpcType">
<xs:sequence>
<xs:element ref="rpcOperation"/>
</xs:sequence>
<xs:attribute name="message-id" type="messageIdType" use="required"/>
<xs:anyAttribute processContents="lax"/>
</xs:complexType>
<xs:element name="rpc" type="rpcType"/>
And is the core to function calls in NETCONF being the node of an XML document. I am curious as to why it is not something like:
<xs:element name="rpcType">
<xs:complexType>
<xs:sequence>
<xs:element ref="rpcOperation"/>
</xs:sequence>
<xs:attribute name="message-id" type="messageIdType" use="required"/>
<xs:anyAttribute processContents="lax"/>
</xs:complexType>
</xs:element>
The reasoning is that in #1 when trying to marshall a bean (in jaxb2) I get the exception:
[com.sun.istack.SAXException2: unable to marshal type "netconf.RpcType" as an element because it is missing an @XmlRootElement annotation]
I have been reading this article over and over again, and really cant get a hold of the difference, and why it would be #1 vs #2...
The complexType element defines a complex type. A complex type element is an XML element that contains other elements and/or attributes.
XSD elements can be of type simpleType , complexType , or anyType . An element of type simpleType contains only text. It cannot have attributes and elements. An element of type complexType can contain text, elements, and attributes.
An attribute provides extra information within an element. Attributes are defined within an XSD as follows, having name and type properties. An Attribute can appear 0 or 1 times within a given element in the XML document. Attributes are either optional or mandatory (by default the are optional).
It's not obvious, I'll grant you. It comes down to the type vs element decision.
When you have something like
<xs:element name="rpcType">
<xs:complexType>
This is essentially an "anonymous type", and is a type which can never occur anywhere other than inside the element rpcType
. Because of this certainty, XJC knows that that type will always have the name rpcType
, and so generates an @XmlRootElement
annotation for it, with the rpcType
name.
On the other hand, when you have
<xs:complexType name="rpcType">
then this defines a re-usable type which could potentially be referred to by several different elements. The fact that in your schema it is only referred to by one element is irrelevant. Because of this uncertainty, XJC hedges its bets and does not generate an @XmlRootElement
.
The JAXB Reference Implementation has a proprietary XJC flag called "simple binding mode" which, among other things, assumes that the schema you're compiling will never be extended or combined with another. This allows it to make certain assumptions, so if it sees a named complexType
only being used by one element
, then it will often generate @XmlRootElement
for it.
The reality is rather more subtle and complex than that, but in 90% of cases, this is a sufficient explanation.
Quite an involved question. There are many reasons to design schemas using types rather than elements (this approach is called the "venetian blind" approach versus "salami slice" for using global elements). One of the reasons is that types can be sub-typed, and another that it may be useful to only have elements global that can be root elements.
See this article for some more details on the schema side.
Now, as for the JAXB question in particular. The problem is that you created a class corresponding to a type and tried to serialise it. That means JAXB knows its content model, but not what the element name should be. You need to attach your RpcType to an element (JAXBElement), for example:
marshaller.marshal(new ObjectFactory().createRpc(myRpcType));
The ObjectFactory
was placed into the package created by JAXB for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With