How to use xsd:all in a set of derived objects?

K

Kunal

I'm unable to use the "xsd:all" tag in derived objects, in a
hierarchical schema setup. For example, I have the following schema
(that doesn't validate with XMLSpy):

(UserOfDerived extends Derived extends Base)

<!-- Base.xsd -->
....
<xsd:complexType name = "Base" abstract = "true">
<attribute name = "revision" type = "xsd:string"/>
<attribute name="id" type="xsd:ID"/>
</xsd:complexType>
....

And I derive most of my objects from this as follows:

<!-- Derived.xsd -->

<complexType name="Derived">
<complexContent>
<extension base="Base">
<all>
<element name="DerivedElement1" type="xsd:string"
minOccurs="0"/>
<element name="DerivedElement2" type="xsd:string"
minOccurs="0"/>
<element name="DerivedElement2" type="xsd:string"
minOccurs="0"/>
<element name="DerivedElement4" type="xsd:string"
minOccurs="0"/>
</all>
</extension>
</complexContent>
</complexType>
....

And finally, I want to extend the Derived object in other objects, as
follows:

<!-- UserOfDerived.xsd -->
....
<xsd:complexType name = "UserOfDerived">
<xsd:complexContent>
<xsd:extension base = "Derived">
<xsd:all>
<xsd:element name = "UserOfDerivedElement1" type = "xsd:string"
minOccurs = "0"/>
<xsd:element name = "UserOfDerivedElement2" type = "xsd:string"
minOccurs = "0"/>
<xsd:element name = "UserOfDerivedElement3" type = "xsd:string"
minOccurs = "0"/>
<xsd:element name = "UserOfDerivedElement4" type = "xsd:string"
minOccurs = "0"/>
<xsd:element name = "UserOfDerivedElement5" type = "xsd:string"
minOccurs = "0"/>
</xsd:all>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
.....

None of this validates with any XML parser. If I convert all "xsd:all"
types to "xsd:sequence" types, it works, but that's not what I want (my
XML message will contain elements in random order, so it's important
that the schema not reflect any ordering).

Any suggestions?
Thanks in advance.
 
S

Soren Kuula

Kunal said:
None of this validates with any XML parser. If I convert all "xsd:all"
types to "xsd:sequence" types, it works, but that's not what I want (my
XML message will contain elements in random order, so it's important
that the schema not reflect any ordering).

Any suggestions?

Yes, give it up ;)

Seriously, the 'all' construct is pretty restricted. As I remember it,
it is only permitted if it is is completely alone in a content model
(not inside a sequence, not inside a choice, not inside an all), and if
it contains just element decls or refs (no seequence, choice or all).

By extending one type from another, you effectively make a sequence of
the two content models. That doesn't work with 'all'.

You might want to quit using derivation (which is not all that good a
feature anyway), and just copy everything you declared in the <all> of
the derived type to its base type, with minOccurs='0' maxOccurs='1' on
'em....

Soren
 
K

Kunal

Thank you for that response.

Although I have ended up expanding (copying) the contents of the base
object into all my derived objects, I'm intrigued by your statement
"quit using derivation (which is not all that good a feature anyway)".
Why is that?

Naturally the problems didn't end there. I have several objects that
are lists (with minOccurs='0' maxOccurs='unbounded' ) and now I have to
figure out a way to use lists with the "all" tags.

Any suggestions? The only one that works for me is to "wrap" the lists
in separate elements, but that means changes to my code that depends on
the list element names.

Thanks!
 
S

Soren Kuula

Kunal said:
Thank you for that response.

Although I have ended up expanding (copying) the contents of the base
object into all my derived objects, I'm intrigued by your statement
"quit using derivation (which is not all that good a feature anyway)".
Why is that?

XML Schema basically descripes what is called "single-type regular tree
languages".

Tree language - it defines languages of trees (not strings, like many
other languages like English, regular expressions or context free
languages .. etc)

Regular tree languages - because the defined-to-be-allowed content of an
element is a regular expression over (names and types) the contained
elements. The choice compositor is the same as | in regular expressions
- sequence is concatenation - element (names and types) are symbols.

Single-type, because at parse-validation time, is soon as an element
name is encountered, the type that the content of the element must be a
member of, is known uniquely and immediately. (there are other tree
languages that are multi-type).

That's the theortical foundation & limitation. The object oriented
principles of type derivation and subsumption don't really have a place
here, and can only be hammered in rather crudely:

- Derivation by extension (adding fields in an OO class) is made into
seqences. In true OO, there _is_ no sequence -- there is a field name to
value mapping, now with some more names and values.

- Derivation by restriction (spacial-case types) must have an xsi:type
attribute on them to preserve the single-typedness.

I prefer just to think of extension of sequences as extension of
sequences, and use fresh element names instead of xsi:type instead of
restriction (in OO, you'd use fresh class names anyway).

All in all, it makes for an overly complicated spec, when mixing the two
worlds (tree and OO).

Maybe I dislike derivation also becuase I fell victim of it, in my
Master's thesis project (http://dongfang.dk/mscthesis/mscthesis.html ; I
think I wrote a decent explanation of the single-typedness stuff there
too (Report in PDF format link)). Maybe I just joined the choir of XML
Schema type system critics (e. g.
http://www.xml.com/pub/a/2001/06/06/schemasimple.html). I do like
substitution groups for some purposes (imitating context free
non-terminals) though.
Naturally the problems didn't end there. I have several objects that
are lists (with minOccurs='0' maxOccurs='unbounded' ) and now I have to
figure out a way to use lists with the "all" tags.

You're busted. 'all' only works with 0 or 1 multiplicity.
Any suggestions? The only one that works for me is to "wrap" the lists
in separate elements, but that means changes to my code that depends on
the list element names.

WELL, basically .... you want a content model of elements appering in
any order, and some of them in any number? That has always been a bit
hard to describe precisely and yet efficiently in regular languages.

If it was my design, I would see (as I think you suggest) if I could
divide everything into sections of some sort, and put each section into
a sub-element.

So, instead of:

<mystuff>
<item-a-1/>
<item-a-2/>
<item-a-2/>
<item-a-3/>
<item-b-1/>
<item-b-2/>
</mystuff>

if you can, without any big trouble, use

<mystuff>
<a-items>
<item-a-1/>
<item-a-2/>
<item-a-2/>
<item-a-3/>
</a-items>
<b-items>
<item-b-1/>
<item-b-2/>
</b-items>
</mystuff>

instead, everything would be easier for you (although a little more
verbose): Content models get smaller. (your DerivedElement's could be
the a's and your UserOfDerivedElement's could be b's. Put a minOccurs=0
and maxOccurs=1 on the b-items element reference in definition of the
type for the mystuff element).

As for the 'all' construct, it does not add any expressiveness to the
language at all: Everything you can do with it, you can do without (yes,
really! The all thing comes from set algebra, and like OO, it is an ugly
intrusion into regular tree languages ... and it leaves a thick, smelly
smoke trace of special rules and can-not-do's behind it...........)

Maybe I would just approximate to
<choice minOccurs="0" maxOccurs="unbounded">
<element............/>
<element............/>
<element............/>
<element............/>
</sequence>
where precisiion is not a big deal.

Hope it helped.

Søren
 
S

Soren Kuula

Kunal said:
Thank you for that response.

Although I have ended up expanding (copying) the contents of the base
object into all my derived objects, I'm intrigued by your statement
"quit using derivation (which is not all that good a feature anyway)".
Why is that?

I forgot to say that of course, derivation provides some code re-use
opportunitites, and that is of course nice. However, groups (<group>,
<group ref="...">) can do that, too. See
http://www.xml.com/pub/a/2001/06/06/schemasimple.html .

Derivation is a good thing with some of those data-binding frameworks:
They can recognize types as substypes of each other, which they would
not have been able to do with groups, or copy-and-paste.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,034
Messages
2,570,356
Members
47,002
Latest member
RobertoLip

Latest Threads

Top