- From: Mikael Joukakelian <mikaelj@cae.com>
- Date: Thu, 5 Sep 2002 16:59:58 -0400
- To:
- Cc: xmlschema-dev@w3.org
Consider the following schema which, if I understood the email below correctly, is valid: <?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:element name="AbstractMenuEntry" abstract="true"/> <xs:element name="MenuStructure"> <xs:complexType> <xs:sequence> <xs:element ref="AbstractMenuEntry" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> <xs:unique name="menuIdConstraint"> <xs:selector xpath="MenuEntry"/> <xs:field xpath="@menuId"/> </xs:unique> </xs:element> <xs:element name="MenuEntry" substitutionGroup="AbstractMenuEntry"> <xs:complexType> <xs:attribute name="menuId"/> </xs:complexType> </xs:element> </xs:schema> This validates in XML Spy, but not in MSXML4.0 and SQC2.1.1. Until recently, I was using XML Spy and life was easy, but I also need to use MSXML4.0 and I get the following error message from SQC2.1.1: SEVERITY: 0 ERROR TYPE: 2 MESSAGE No node in element MenuStructure corresponds to <xs:selector xpath="MenuEntry"/> defined in <xs:unique name="menuIdConstraint"> <selector xpath="MenuEntry"/> <field xpath="@menuId"/> </xs:unique> . Invalid XPath starting from MenuStructure:MenuEntry. XML Spy doesn't even check if menuId exists anywhere, that is, changing <xs:field xpath="@menuId"/> to <xs:field xpath="@menuId777"/> would not generate an error. Would this be a W3C conformant schema even if menuId777 does not exist? With SQC2.1.1, menuId is not found within the context of MenuStructure even though it is there by substitution of the AbstractMenuEntry abstract element. It seems that, this validator seeks to resolve the field xpath and this without checking all the possible substitutions. Even if it were to try to check, it is an impossible feat, since another schema file may include this one and define a new element with an AbstractMenuEntry substitution group. So requiring the existence of the element/attribute pointed to by the xpath is limiting when working with abstract elements. I am stuck. How can I specify (in a way that pleases SQ2.1.1 and MSXML4.0) that all the MenuEntry elements of MenuStructure must have unique menuId? I would be pleased to hear of a workaround to this problem. What does the W3C consider as valid in this case? Thanks in advance. -----Original Message----- Date: Wed, 9 Jan 2002 10:15:58 +0000 From: Jeni Tennison <jeni@jenitennison.com> Message-ID: <83178716961.20020109101558@jenitennison.com> To: "Patrick Lisser" <patrick.lisser@canoo.com> CC: xmlschema-dev@w3.org Subject: 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 Thursday, 5 September 2002 17:01:16 UTC