- From: Patrick Lisser <patrick.lisser@canoo.com>
- Date: Wed, 9 Jan 2002 04:52:10 -0500 (EST)
- To: "Jeni Tennison" <jeni@jenitennison.com>
- Cc: <xmlschema-dev@w3.org>
Wow - great answer! Many aspects I never would have thought of! At the moment I'm intending to use a model group, however I have a question about an additional aspect: unique/key constraints. My menu entries have additionally an attribute "menuId" of the type xs:ID (which is referenced by other element's attributes of the type xs:IDREF). Because the ID value must be unique in the whole XML document and this is an unnecessarily strong constraint (the menu id only needs to be unique within the <MenuStructure>...</MenuStructure> subtree) I intend to change the types to xs:string and to add unique or key constraints. For example: <xs:element MenuStructure ...> ... <xs:unique name="menuIdConstraint"> <xs:selector xpath="AbstractMenuEntry"/> <!-- substitution group --> <xs:field xpath="@menuId"/> </xs:unique> </xs:element> <xs:element MenuStructure ...> ... <xs:unique name="menuIdConstraint"> <xs:selector xpath="SomeMenu"/> <!-- model group --> <xs:field xpath="@menuId"/> </xs:unique> </xs:element> Now I wonder whether such constraints work better/easier/not-at-all with model group and substitution group (I didn't try hard yet, but until now nothing worked. Have first to read more about these unique/key constraints). I.e. should the constraints above work even if there are some menus (e.g. <Spacer/>) which do not have a menuId (I'd guess that it works with the unique constraint but not with the key costraint)? Or would I have to specify a constraint covering the concrete menu entries, which would be MenuEntry and DynamicMenuEntry, directly? thanks again for the valuable support! pat > -----Original Message----- > From: Jeni Tennison [mailto:jeni@jenitennison.com] > Sent: Tuesday, January 08, 2002 6:24 PM > To: Patrick Lisser > Cc: xmlschema-dev@w3.org > Subject: Re: group or abstract type? > > > Hi Patrick, > > > So the <xs:choice .... </xs:choice> part is dublicated. To simplify > > (and to express that it's really 2 times the same) I'd like to > > consolidate it and I see two possibilities to do so: > > > > 1. I extract the part, add and use it as a group: > [snip] > > 2. Specify a abstract type and substitute it in the concrete menu > > entries: > [snip] > > What are the advantages and disadvantages of both solutions? Are > > there recommendations on what should be preferred under certain > > circumstances? I could imagine that if part of the schema (i.e. the > > group/abstract type) would be external and not modifiable for those > > who wanted to add new concrete menu entries, the choice should be > > the abstract type, however in my situation this is not the case. > > Interesting question. Differences that leap out at me: > > Model group control: > When you use a substitution group, you get a very basic choice, with > the min/max occurrence of the head element determining how many > occurrences there can be of the other elements. On the other hand, > with a xs:choice in a xs:group you can force different elements to be > repeated different numbers of times or, if you need to later on, > refine the model group to give tighter control over the content. > > Namespaces: > When you use a substitution group, all the elements have to be > declared at the top level of the schema, as global elements. This > means that they must all be in the target namespace for the schema. On > the other hand, if you declare the elements within the xs:group, they > are local elements and could be in no namespace (unqualified) instead. > > Naming conflicts: > In general, declaring global elements leads to the possibility of > conflicting element declarations - if you had another element of the > same name but with a different type, and this element also had to be > declared at the top level of the schema (because it was the document > element, or because it was a member of a substitution group too) then > you would run into difficulties. > > Multiple groups: > An element can only belong to one substitution group, but (if it's > declared as a global element) it can be in multiple xs:groups. So if > you have the same issue with a group involving the same element > elsewhere in the schema, it probably makes more sense to use xs:group > throughout. > > Extending into different namespaces: > If someone were to take your schema and want to extend the choice > group to include elements in their own namespace, the amount of effort > they would have to go to is different in the two cases. To extend the > xs:group, they'd have to create an 'adapter' schema in your namespace > that redefined the xs:group, adding references to the elements in > their namespace. On the other hand, with a substitution group they > just need to declare their elements (at the top level) and point to > the abstract substitution group head element, effectively extended the > choice with their own elements. The same issues are involved with > extensions in the same namespace, but the effort is slightly less > marked. > > Control over element types: > Using a substitution group gives you some control over the content of > the extra elements that other people might add, because the types of > the elements that are members of a substitution group must be derived > from the type of the head of the substitution group (your abstract > element). On the other hand, people could put all sorts of elements in > the xs:group if they redefined it. > > > I think my conclusion is that if you're fairly happy that you're not > going to need to change your basic schema (and assuming that it > doesn't contain any conflicts), want to make it easy for people to > extend the allowed elements, and especially if you want to control > what kinds of elements they can extend with, go for a substitution > group. Otherwise, use a model group. > > Cheers, > > Jeni > > --- > Jeni Tennison > http://www.jenitennison.com/ > >
Received on Wednesday, 9 January 2002 09:41:09 UTC