Re: group or abstract type?

Hi Pat,

> Now I wonder whether such [identity] 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).

To summarise the way identity constraints work... The location of the
identity constraint determines its scope. The xs:selector XPath points
to all the elements that have identities within that scope. The
xs:field XPaths go from those elements to the elements/attributes that
give them their identity.

Unfortunately (in some ways), identity constraints work with a
different kind of model of the instance document than the rest of XML
Schema, and don't allow you to select elements based on things like:

  - their membership of substitution groups
  - their type
  - the group in which they're declared

All that the XPaths 'see' when they're evaluated is the node tree of
the instance document. So if you do:

<xs:element name="MenuStructure">
  ...
  <xs:unique name="menuIdConstraint">
    <xs:selector xpath="AbstractMenuEntry"/>
    <xs:field xpath="@menuId"/>
  </xs:unique>
</xs:element>

all it means is that all the AbstractMenuEntry elements that are
direct children of the MenuStructure element must have unique values
for their menuId attributes. This constraint does not apply to any
other child elements of the MenuStructure element (so actually imposes
no constraint at all, since AbstractMenuEntry elements never appear in
the instance document).

To say "all child elements of a MenuStructure element that have a
menuId attribute must take a different value for that menuId
attribute", you need to use a wildcard:

<xs:element name="MenuStructure">
  ...
  <xs:unique name="menuIdConstraint">
    <xs:selector xpath="*"/>
    <xs:field xpath="@menuId"/>
  </xs:unique>
</xs:element>

Alternatively, you could list the possible elements, but I think this
would lead to a lot of work overall, considering you want people to be
able to extend the list of possible children.

> 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)?

That's right - the unique constraint just checks that those elements
that have values for whatever fields you use have unique combinations
of values, whereas the key constraint also checks that all the
elements you select have values for those fields. I think that the
unique constraint is the one that you should use.

> Or would I have to specify a constraint covering the concrete menu
> entries, which would be MenuEntry and DynamicMenuEntry, directly?

See above. You could do:

<xs:element name="MenuStructure">
  ...
  <xs:unique name="menuIdConstraint">
    <xs:selector xpath="MenuEntry | DynamicMenuEntry"/>
    <xs:field xpath="@menuId"/>
  </xs:unique>
</xs:element>

but if someone wanted to add a possible element to the list, they'd
have to redefine the MenuStructure element. I think a wildcard is
probably better if you want to support extensions to the content
model.

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/

Received on Wednesday, 9 January 2002 05:16:05 UTC