XSD complexType definition without indicators - xsd

if i want to define a complex type, i can go
<xs:complexType name="personinfo">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
or, i can replace the
<xs:sequence> ... </xs:sequence>
tag in the above with
<xs:all> ... </xs:all>
or
<xs:choice> ... </xs:choice>
and it validates.
However, these are imposing restrictions on the order/occurrence of the elements.
Is there a way to define a complex element without any of these indicators?
Been "inspired" with
<xs:complexType name="personinfo2">
<xs:complexContent>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:complexContent>
</xs:complexType>
so far, but didn't work.

You really should read a tutorial on XSD.
No, you cannot define a content model without specifying (explicitly or implicitly) one of xs:sequence, xs:choice, or xs:all.
If you want to make no restrictions on the sequence or number of occurrences of your child elements, then what you probably want is:
<xs:complexType name="sample">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="e1" type="xs:string"/>
<xs:element name="e2" type="xs:string"/>
</xs:choice>
</xs:complexType>
This allows any number of e1 and e2 children, in any order. If you find that you don't want any valid elements of type personinfo to contain 37 lastname elements and 36 firstname elements, in alternation, then you have discovered something about what you do and don't want.

Related

XSD: Divide scheme using a choice of sequences

A part of my xsd looks as follows:
<xs:element name="my_element" minOccurs="1 maxOccurs="unbounded">
<xs:complexType>
<xs:choice>
<xs:sequence>
<xs:element name="sequence_1" type="xs:string"/>
<xs:element name="ID1" type="xs:string"/>
<xs:element name="TYPE1" type="xs:string"/>
</xs:sequence>
<xs:sequence>
<xs:element name="sequence_2" type="xs:string"/>
<xs:element name="ID2" type="xs:string"/>
<xs:element name="TYPE2" type="xs:string"/>
</xs:sequence>
</xs:choice>
</xs:complexType>
</xs:element>
The first element name of the sequence decides about th following nodes.
If I now have a lot of different sequences with some elements inside my xsd doesn't look very clear.
Is it possible to separate the sequences (like I can do it for complexType)?
You can use group :
<xs:group name="seqGroup_x">
<xs:sequence>
<xs:element name="sequence_x" type="xs:string"/>
<xs:element name="ID" type="xs:string"/>
...
</xs:sequence>
</xs:group>
<xs:complexType name="yourType">
<xs:group ref="seqGroup_x"/>
<xs:attribute name="anotherattr" type="xs:string"/>
</xs:complexType>

Using x:anyType instead of xsi:type gives Jaxb marshalling errors

I want to avoid xsi:type in an element and add the child elements at runtime based on some condition
I have option element defined as follows of type xs:anyType
<xs:complexType name="prod">
<xs:sequence>
<xs:element type="xs:anyType" name="option" minOccurs="0" maxOccurs="1"</xs:element>
</xs:sequence>
</xs:complexType>
used in element mapping as follows
<xs:element name="mappings">
<xs:complexType>
<xs:sequence>
<xs:element type="prod" name="productionSystem" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
I have need to add following option type as one of the following
<xs:complexType name="Text">
<xs:sequence>
<xs:element type="xs:short" name="id" />
<xs:element type="xs:string" name="name" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="Value">
<xs:sequence>
<xs:element type="xs:short" name="id" />
<xs:element type="xs:string" name="name" />
<xs:element name="psValue" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="value" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
so basically one element option can be either of type Text or Value.
I want to avoid xsi:type in the xml. hence defined as xs:anyType. However at runt time Jaxb Marshalling fails with error
"any of its super class is known to this context". How to ensure Text and Value are in Jaxb Context.
Can someone pls guide on same.
Thanks,
Anjana

Unique constraint on a complexType instead of an element

I have the following XSD structure:
<xs:schema xmlns:ns="http://abc/">
...
<xs:element name="abc">
<xs:complexType>
<xs:sequence>
<xs:element ref="map"/>
</xs:sequence>
</xs:complexType>
</xs:element>
...
<xs:element name="map">
<xs:complexType>
<xs:sequence>
<xs:element name="entry" type="ns:MapEntryType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:unique name="entry">
<xs:selector xpath="entry"/>
<xs:field xpath="key"/>
</xs:unique>
</xs:element>
<xs:complexType name="MapEntryType">
<xs:sequence>
<xs:element name="key" type="xs:string"/>
<xs:element name="value" type="xs:anyType"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
This is doing its job.
The map element now has to be called something different based on whichever is the wrapper, so the name is sometimes map, sometimes properties, sometimes options, etc.
Therefore I want to genericize the map element.
I tried doing the following:
Making map a xs:complexType and changing ref to type.
This resulted in xs:unique not being accepted and failed
Making map a xs:complexType, changing ref to type and moving the xs:unique constraint to the element definitions.
This worked but resulted in the XSD having a lot of xs:unique present in the document.
Isn't there a way to simply tell that I want a specific structure and it containing unique elements without having to repeat the unique constraint everywhere?
As Petru Gardea said in his answer
Both XSD 1.0 and 1.1 place the identity constraints under an element
So you have to add xs:unique to every element, but if you are using XSD 1.1 you can define only once a complete xs:unique and then in the rest of the elements use xs:unique ref="name". This is not valid for you as you are using XSD 1.0, but I let it here for future XSD 1.1 users that find this good question.
Example (namespaces removed for clarity):
<xs:element name="map">
<xs:complexType>
<xs:sequence>
<xs:element name="entry" type="MapEntryType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<!-- Only completely defined once -->
<xs:unique name="uniqueEntry">
<xs:selector xpath="entry"/>
<xs:field xpath="key"/>
</xs:unique>
</xs:element>
<xs:element name="hashMap">
<xs:complexType>
<xs:sequence>
<xs:element name="entry" type="MapEntryType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<!-- Referenced here and every other time -->
<xs:unique ref="uniqueEntry"/>
</xs:element>
Short answer, it is not possible. Both XSD 1.0 and 1.1 place the identity constraints under an element; a constraint cannot be globally defined, therefore there is no "reuse" per se, other than that of the enclosing element. Given your scenario (different element names for different needs) it is not possible to reuse.

XSD Schema - how to ensure that two simple elements either have values or do not have values together

please assist, this is what i want to achieve in validating my xml file:
<?xml version="1.0" encoding="UTF-8"?>
<worker>
<name>dingo</name>
<ssn>12345</ssn>
</worker>
I want to ensure that the two simple elements 'name' and 'ssn' either have values (as a group) or do not have any value (as a group). They cannot exist individually with a value.
I have to use an XSD schema, so cannot use other options i see suggestions sometimes: Relax NG etc.
I looked into creating a group for elements 'name' and 'ssn' but i am unable to find out how to create a restriction for this group to obtain my condition.
My current XSD file:
<xs:complexType name="worker">
<xs:sequence>
<xs:element name="name" type="xs:string" minOccurs="0" "maxOccurs="1">
<xs:element name="ssn" type="xs:positiveInteger" minOccurs="0" "maxOccurs="1">
</xs:sequence>
</xs:complexType>
<xs:complexType name="worker">
<xs:sequence minOccurs="0">
<xs:element name="name" type="xs:string">
<xs:element name="ssn" type="xs:positiveInteger">
</xs:sequence>
</xs:complexType>
You have to do
<xs:complexType name="worker">
<xs:group ref="workerGrp" minOccurs="0"/>
</xs:complexType>
<xs:group name="workerGrp">
<xs:sequence>
<xs:element name="name" type="xs:string">
<xs:element name="ssn" type="xs:positiveInteger">
</xs:sequence>
</xs:group>

XSD - Override element

I've a base class, marked as abstract:
<!-- TYPE: BASE CLASS -->
<xs:complexType name="BaseClass" abstract="true">
<xs:sequence>
<xs:element name="name" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="implementation" type="BaseClass" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
Now the class that inherits BaseClass and overrides 'implementation' with null:
<xs:complexType name="MyClass">
<xs:complexContent>
<xs:extension base="BaseClass"/>
</xs:complexContent>
</xs:complexType>
I've tried this but is invalid:
<xs:complexType name="MyClass">
<xs:complexContent>
<xs:extension base="BaseClass">
<xs:sequence>
<xs:element name="implementation" fixed="xs:nil"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
Is there a way to do this?
Marking something as abstract in XSD schema basically means that it cannot appear in an instance document. It should be used with the substitutionGroup attribute.
For example
<xs:element name="replaceme" abstract="true" />
<xs:element name="replacement1" substitutionGroup="replaceme" />
<xs:element name="replacement2" substitutionGroup="replaceme" />
This means that in an instance document you would be forced to use either a "replacement1" or a "replacement2" element, ie the xsd is forcing you to substitute the "replaceme" element with one of the replacements from the substitution group.
So to achieve what you want you need to create a substitution group consisting of the types you want to use instead of your base type. I am not sure this is possible with complex types but give it a go.

Resources