Extend complextype from element - xsd

Suppose I have define a general complextype
<xs:complexType name="Address">
<!--definition of address-->
</complexType>
now suppose I want to define a new type of address that will be used only once, and i want to extend the complextype address in a a new element
e.g.
<element type="Address">
<!--how to extend the base type address here-->
</element>
I don't want to define a new complex type to extend the type address because it will be used only once

You probably want an anonymous complex type; being anonymous, it can't be referenced, so effectively you can use it only "once".
<xsd:complexType name="Address">
<!-- definition of address -->
</xsd:complexType>
<xsd:element name="AnotherAddress">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="Address">
<!-- Extra content for address -->
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>

Related

XSD two elements with the same inner structure

I am working with an xsd, trying to get it to validate an xml.
The xml is used to create objects. There are two types of objects that can be created by the elements in the list: SC and SMSC. SMSC is an SC, and extends it.
SMSC doesn't contain any new properties. From the perspective of the xml, an SMSC is identical to an SC in every way, except that the elements that define its properties are wrapped by <SMSC> tags instead of <SC> tags.
Our XSD looks like this:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name='Definitions'>
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="unbounded" name="SC">
<!--SNIP properties of SC and SMSC -->
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
Is there a way to change this to allow either SC or SMSC as the element, other than duplicating all of the property definitions in an SMSC element? We don't want to have to double the length of the document and duplicate all of the property definitions.
As it stands, the only validation error we have in our XML is where we have an SMSC element. If there isn't a way to fix this without duplicating all the property definitions we'll leave it as-is, but we'd obviously prefer to eliminate the warning this throws if practical.
While it is confusing by tags instead of tags, I would think that below is either answering your question, or elicits better explanations.
So, what you see is avoiding duplication; you don't actually need the additional type SMSC (see Definitions2), but I've put it just in case (Definitions). Making the SMSC element of the SC type would work exactly the same.
The difference between Definitions / Definitions2 and Definitions3 is that one uses substitution groups instead of choices. I personally prefer substitution groups to choices, yet is not that uncommon to run into issues related to substution groups (i.e. they are poorly supported here and there).
<?xml version="1.0" encoding="utf-8" ?>
<!-- XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com) -->
<xsd:schema targetNamespace="http://tempuri.org/XMLSchema.xsd" xmlns="http://tempuri.org/XMLSchema.xsd" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:complexType name="SC">
<xsd:sequence>
<!-- Stuff goes here -->
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="SMSC">
<xsd:complexContent>
<xsd:extension base="SC"/>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="Definitions">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="SC" type="SC"/>
<xsd:element name="SMSC" type="SMSC"/>
</xsd:choice>
</xsd:complexType>
</xsd:element>
<!-- Another way -->
<xsd:element name="Definitions2">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="SC" type="SC"/>
<xsd:element name="SMSC" type="SC"/>
</xsd:choice>
</xsd:complexType>
</xsd:element>
<xsd:element name="Definitions3">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="SC" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="SC" type="SC" />
<xsd:element name="SMSC" type="SMSC" substitutionGroup="SC" />
</xsd:schema>

Invalid particle derivation by restriction for schema

How can I remove the below warning in the xsd. mymain.xsd refers to mysecond.xsd
my main.xsd
<?xml version="1.0" encoding="UTF-8"?><xsd:schema elementFormDefault="qualified" targetNamespace="http://abc.com" version="2.0" xmlns:tyu="http://abc.com" xmlns:my="def.com" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:import namespace="def.com" schemaLocation="mysecond.xsd"/>
<xsd:complexType name="myType">
<xsd:complexContent>
<xsd:restriction base="my:myType">
<xsd:sequence>
<xsd:element minOccurs="0" name="rty" type="tyu:myagainType"/>
</xsd:sequence>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="myagainType">
<xsd:complexContent>
<xsd:restriction base="my:myagainType">
<xsd:sequence>
<xsd:element minOccurs="1" name="uid">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:maxLength value="1"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
</xsd:sequence>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
</xsd:schema>
mysecond.xsd
<?xml version="1.0" encoding="UTF-8"?><xsd:schema elementFormDefault="qualified" targetNamespace="def.com" version="2.0" xmlns:my="def.com" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:complexType name="myagainType">
<xsd:sequence>
<xsd:element minOccurs="0" name="klo" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="myType">
<xsd:sequence>
<xsd:element minOccurs="0" name="rty" type="my:myagainType"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
warning
Warning 1 Invalid particle derivation by restriction - 'Derived element 'http://abc.com:rty' is not a valid restriction of base element 'def.com:rty' according to Elt:Elt -- NameAndTypeOK.'. D:\files\mymain.xsd 3 4
Short answer, you cannot. To begin with, your rty in mySecond.xsd is locally defined and qualified and in a different namespace than the "equivalent" rty in the main.xsd, the latter also locally defined and qualified in a different namespace.
If you go through the XML Schema spec, part 2, you'll get an explanation for each rule that applies to a valid restriction. In your case, you either use the same named element (start by "unqualifying" the rty element), or a member of a substitution group.
You obviously don't want the same element, since it'll give you the same content model - you have one element only. One reason people use restriction is to reduce the content model (remove elements from the list) and/or fiddle with min/maxOccurs for particles.
You can't do things using substitution groups since you defined rty locally; the head of a substitution group must be defined globally.
To allow for what you want, you have to completely rewrite your XSD. A better description around what exactly you're trying to achieve along with any constraints you place on XSD authoring (e.g. use of substitution groups, or redefine, or the context in which your XSDs will be used) may help others provide you with better answers.

Using XmlRootElement in JAXB to avoid root JAXBElement

I am unmarshalling messages conforming to the schema below and would like the returned root element to be of class Bar. Instead, the root element returned is always a JAXBElement containing the name 'foo' with a value equal to the desired Bar element.
I think that XmlRootElement can be used to do this in a bindings file but haven't got this to work yet. Any ideas?
<xsd:element name="foo" type="Bar"/>
<xsd:complexType name="Bar">
<xsd:sequence>
<xsd:element name="goo" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
Since there could be many global elements that correspond to a global complex type, a JAXB impl does not generate an #XmlRootElement annotation on these classes. You could declare the element with an anonymous complex type.
<xsd:element name="foo">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="goo" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
When the unmarshal method returns an instance of JAXBElement you can obtain the domain object by calling getValue().
You can customize your xsd:element with jaxb:class, this will generate an extra class for your element. This customization can be done via bindings:
<jaxb:bindings node="xsd:element[#name='foo']">
<jaxb:class>
</jaxb:bindings>

XSD Extension with Element AND Attribute

I need to create an XSD which would validate the following type of XML:
<dbengine stylesheet="file:transformation.xslt">
<queries>
<query name="update" inputtype="file">file:/src/test.sql</query>
<query name="update" inputtype="sql">select * from test</query>
</queries>
</dbengine>
This can be done by formulating the following schema:
<xsd:element name="dbengine">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="queries" type="queries" minOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="stylesheet" type="xsd:string" use="optional"/>
</xsd:complexType>
</xsd:element>
Additionally, I need this tag to be able to receive and send messages from/to a channel by extending inputOutputEndpointType from http://www.springframework.org/schema/integration/spring-integration-1.0.xsd. So ideally I should have something like this:
<xsd:element name="dbengine">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="int:inputOutputEndpointType" >
<xsd:sequence>
<xsd:element name="queries" type="queries" minOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="stylesheet" type="xsd:string" use="optional"/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
However this results in an error (in the eclipse editor):
cos-ct-extends.1.4.3.2.2.1.a: The content type of a derived type and
that of its base must both be mixed or both be element-only. Type
'#AnonType_dbengine3' is element only, but its base type is not.
Adding the mixed="true" attribute doesn't help and every other attempt of solving this failed so far.
I tried your schema in my XML Schema editor and I did not get any error for your snippet (I had to put it within an xsd:schema, and add a dummy definition for the queries complex type).
I think you're simply experiencing an issue with the Eclipse editor. The living proof is in the same file, please take a look at the "innerEndpointDefinitionAware" complexType.
One thing you should try with Eclipse is to actually download spring-integration-1.0.xsd, spring-beans-2.0.xsd and sprint-tool-2.0.xsd in the same folder. Edit the integration file to make sure that for the xsd:imports you manually add the schemaLocation to the files you've downloaded. Try again and see what happens. If it works, the issue is then related to the "dangling" approach used by almost all of the Spring schemas (use of xsd:import without the schemaLocation). With dangling definitions, it is up to the schema processor (in your case provided by Eclipse) to resolve those namespaces.
With my editor it worked even without downloading, after I've configured it to resolve the dangling definitions to the appropriate versions of the beans and tools - maybe Eclipse supports the same?
I couldn't find a way to implement it, here my workaround. I just created a new complexType which substitutes spring inputOutputEndpointType.
<xsd:complexType name="workaround">
<xsd:attribute name="output-channel" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.integration.core.MessageChannel" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="input-channel" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.integration.core.MessageChannel" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="order" type="xsd:string">
</xsd:attribute>
<xsd:attribute name="auto-startup" type="xsd:string" />
</xsd:complexType>
in the dbengine tag I extend this complexType:
<xsd:extension base="workaround" >

XJC Generating Integer Instead of int

The following schema should be generating two primitive int fields in a Value class, but instead generates a primitive int for the element and java.lang.Integer for the attribute.
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema version="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.com/test" xmlns:test="http://www.example.com/test"
elementFormDefault="qualified">
<xsd:element name="values">
<xsd:complexType>
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="test:value" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="value">
<xsd:complexType>
<xsd:sequence>
<!-- Is generated as primitive int -->
<xsd:element name="element" type="xsd:int" />
</xsd:sequence>
<!-- Is generated as java.lang.Integer -->
<xsd:attribute name="attribute" type="xsd:int" />
</xsd:complexType>
</xsd:element>
</xsd:schema>
I've looked through the JAXB documentation for anything that says that attributes and elements may be generated differently and found nothing.
Can anyone explain this? Is there a fix to make the attribute generate as a primitive int?
I'm not entirely sure this is the answer, but I had an epiphany while debugging my app.
The default multiplicity for an element in an XML schema is 1..1 (required) where as the default multiplicity for an attribute is 0..1 (optional).
So, since the element is required and a primitive in Java has a default value (most likely 0), it makes sense to generate an <xsd:element type="xsd:int" /> as a Java primitive.
Since the attribute is optional there is a possibility that it may be nillable which would not be possible using a primitive. The java.lang.Integer is an Object and thus allowed to be null, so it makes sense to generate an <xsd:attribute type="xsd:int" /> as an java.lang.Integer.
If you make an attribute be required (<xsd:attribute type="xsd:int" use="required" />), it will generate as a primitive int. I haven't seen documentation by JAXB that explicitly says this, but that doesn't mean it doesn't exist; perhaps I just missed it.

Resources