This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 8119 - defaultAttributes and complexType extension/restriction don't play nice
Summary: defaultAttributes and complexType extension/restriction don't play nice
Status: CLOSED WORKSFORME
Alias: None
Product: XML Schema
Classification: Unclassified
Component: Structures: XSD Part 1 (show other bugs)
Version: 1.1 only
Hardware: PC Windows XP
: P2 normal
Target Milestone: ---
Assignee: David Ezell
QA Contact: XML Schema comments list
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-10-28 21:14 UTC by Kevin Braun
Modified: 2010-11-10 17:13 UTC (History)
2 users (show)

See Also:


Attachments

Description Kevin Braun 2009-10-28 21:14:06 UTC
Consider this XSD 1.1. schema:

<xs:schema
   xmlns:xs="http://www.w3.org/2001/XMLSchema"
   defaultAttributes="AttrGroup"
>
 
   <xs:attributeGroup name="AttrGroup">
      <xs:attribute name="a_default" type="xs:string"/>
   </xs:attributeGroup>

   <xs:complexType name="TypeA">
   </xs:complexType>

   <xs:complexType name="TypeB">
      <xs:complexContent>
         <xs:extension base="TypeA">
         </xs:extension>
      </xs:complexContent>
   </xs:complexType>
</xs:schema>


I believe this is not valid, because TypeB's {attribute uses} will have two "a_default" attributes.  At least, this would be true if I had explicitly defined the same attribute in TypeA and TypeB, and I don't see any exception for default attributes.  This can be resolved by using defaultAttributesApply="false" on TypeB, but that is both annoying and counterintuitive (because it will still inherit the default attributes).  

Something somewhat similar happens for restrictions, but only if you try to restrict a default attribute.  The attribute will then be present twice in {attribute uses} - once from the default attributes group and once for the explicit <attribute> child.  The effect seems to be that you cannot restrict a default attribute, unless you specify defaultAttributesApply="false".  Another situation arises if you try to restrict a type that didn't have the default attributes.  In that case, if defaultAttributesApply="true", you'll be adding attributes in the restriction, which will be a problem unless they happen to restrict an attribute wildcard (as in the case of an implicit complexContent).

Perhaps default attributes should not apply to derived types (ie, act as if defaultAttributesApply="false" were specified).  For an extension, defaultAttributesApply="true" is only useful in a few cases, and in those cases, the attributes could still be added by an explicit reference to the attribute group.  For a restriction, defaultAttributesApply="true" will cause one of the above problems or have no effect whatsoever.  Meanwhile, there doesn't seem to be any reason to ever use defaultAttributesApply="false" for a restriction, other than to avoid the above problems.  Yet, there is the case of restriction of xs:anyType coming from using an implicit complexContent, where you do want defaultAttributesApply="true".

It seems like making "defaultAttributesApply" a property of the ComplexType component, and having some rules to set it appropriately might be a way to solve these rather nasty problems.
Comment 1 C. M. Sperberg-McQueen 2009-10-30 23:58:01 UTC
Having looked at this for a while, I agree with the analysis of the examples in the description.  I also agree that it may prove mildly tedious in practice to have to set defaultAttributesApply = "false" on so many complex types, at least in some styles of schema specification.  But I don't think there are any logical inconsistencies here, and (how shall I put this tactfully?) if this is the worst usability problem XSD 1.1 has, we've done better than I thought.  Perhaps I'm just tired, late on a Friday afternoon, but I place more weight on XSD 1.1 moving forward soon than on whatever improvement might be possible in the details of the design of this feature.

Yes, if in extending or restricting a complex type you modify any of the default attributes, or even if you specify default attributes and then, in the same schema document, define numerous complex types by extension or restriction of other complex types defined in the same schema document, then you will have extra work to do.  The situation has at least the advantage that the processor will call your attention to the error, and it's the kind of mistake you won't make more than two or three times.  In that sense, this feature compares favorably (for some users) with the default value of elementFormDefault, which in my experience takes more than two or three goes to learn thoroughly.

So (speaking only for myself), I am inclined to decline this bug report either with WONTFIX (if we agree that there is a problem) or with INVALID (if the WG wishes to maintain that properly regarded it really isn't a problem in the first place). 
Comment 2 Michael Kay 2009-10-31 00:33:34 UTC
I'm inclined to agree. Compared with some of the usability problems in 1.0, like attribute groups being combined by intersection rather than by union, and content models in a restricted type having to be repeated on the derived type, this is pretty minor; and it's not clear there's a simple change that would make life better for everyone. defaultAttributes is a schema-document-wide default, which makes sense if you want to use the same value on most declarations in the schema document; if you don't want to use the same value on most declarations, then you don't have to use it.
Comment 3 Kevin Braun 2009-11-02 15:10:16 UTC
Yes, it really is a usability issue and not a logical inconsistency.  I understand the point about its relative impact versus getting 1.1 out.

However, it does seem to me rather unfortunate if this feature goes out as-is.  Assume that I want every complex type to have the default attributes.  The intent seems to be that I would then just specify defaultAttributes="XYZ" on the schema.  However, in reality, since defaultAttributesApply="true" is the default for all complex types, I must additionally specify defaultAttributesApply="false" for all types that extend a complex type.  Otherwise, I'll get errors for duplicate attributes.  So, the feature doesn't seem to quite work the intended magic, which I think is unfortunate.

I think something along the following lines would be closer to having the intended effect.  Let defaultAttributesApply be a property of the ComplexType component, set in the following way:
   if the "defaultAttributesApply" attribute is present: the specified value
   else if complex type with implicit content: true
   else if derivation method = restriction:  false
   else if derivation method = extension
      if the base type is a simple type : true
      else if the base type is a complex type: false

There might still be some oddball cases, but I think this would let a user specify "defaultAttributes" on the schema and get every complex type having the default attributes without having to do anything extra.

I would think if you include this feature in 1.1, you want it to work as intended and that if it doesn't work as intended now, it won't be easy to change later.  If you agree that it doesn't quite achieve what you wanted, you might not want to put it in at all, or else fix it?

Comment 4 Sandy Gao 2009-11-09 16:30:51 UTC
This, to me, looks more like a question about component identity.

In the example in comment #0, there is a single attribute group definition component, with a single attribute use component in its {attribute uses} property.

When the {attribute uses} of "TypeB" is calculated, we say it's "a union of sets of attribute uses as follows". The 2 sets here are {attribute uses} from the global attribute group definition (defaulted) and {attribute uses} from "TypeA" (inherited). Given that there is a *single* attribute use component, the union should *not* result in 2 entries in "TypeB"'s {attribute uses}, and the relevant constraint (clause 4 of section 3.4.6.1) is *not* violated.

I do agree that component identity is not as clearly specified as one would like in the spec, but this case is no worse than other cases where we depend on identity, for example, clause 2.1 of section 3.4.6.5.

> I believe this is not valid, because TypeB's {attribute uses} will have two
> "a_default" attributes.  At least, this would be true if I had explicitly
> defined the same attribute in TypeA and TypeB

These 2 cases are different. 2 references to the same attribute group component result in a single attribute use; 2 locally declared attributes result in 2 distinct attribute use components.

Now back to clause 4 of section 3.4.6.1:

"4 No two distinct attribute declarations in the {attribute uses} have identical expanded names."

Trying to understand what it means. Would 2 attribute uses with the *same* attribute declaration but different, say, fixed value be allowed? (This can happen when there are 2 references to the same global attribute declaration.) I would think no. Maybe it meant to say the following instead?

"4 No attribute declarations of two distinct attribute uses in the {attribute uses} have identical expanded names."

(1.0 uses different words for this rule, but seems to have the same issue.)
Comment 5 Kevin Braun 2009-11-09 20:27:30 UTC
> In the example in comment #0, there is a single attribute group definition
> component, with a single attribute use component in its {attribute uses}
> property...

> ...there is a *single* attribute use component, the union should *not* result 
> in 2 entries in "TypeB"'s {attribute uses}, and the relevant constraint 
> (clause 4 of section 3.4.6.1) is *not* violated.

> ... These 2 cases are different. 2 references to the same attribute group
> component result in a single attribute use; 2 locally declared attributes
> result in 2 distinct attribute use components.

Good point.  I missed this.

As a side note, here is a schema that would present the same case, I think.  XSV and Xerces both report errors on it:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

   <xs:attributeGroup name="AttrGroup">
      <xs:attribute name="a_default" type="xs:string"/>
   </xs:attributeGroup>

   <xs:complexType name="TypeA">
      <xs:attributeGroup ref="AttrGroup"/>
   </xs:complexType>

   <xs:complexType name="TypeB">
      <xs:complexContent>
         <xs:extension base="TypeA">
            <xs:attributeGroup ref="AttrGroup"/>
         </xs:extension>
      </xs:complexContent>
   </xs:complexType>

</xs:schema>
XSV reports: 11:4: Invalid: attempt to extend with an attribute already declared {{None}:a_default}
Xerces reports: [14,49]: ct-props-correct.4: Error for type 'TypeB'. Duplicate attribute uses with the same name and target namespace are specified.  Name of duplicate attribute use is 'a_default'.

Based on the above, I assume these implementations are incorrect; there is only a single attribute use component involved.

Given the above, some of what I said would no longer be an issue.  You would still have some cases of restriction where a default of defaultAttributesApply="false" would be preferable, but it becomes less of an issue.

Other than perhaps adopting Sandy's suggested revision of clause 4 of section 3.4.6.1, I think this can be closed.  Sorry for taking your time.
Comment 6 David Ezell 2009-11-20 14:55:34 UTC
The WG discussed this issue on the telcon of 2009-11-06, and decided not to make the recommended change.  This decision was made after considering the comments, and the final indication from Kevin Braun that he can live with the status quo.  

The WG also discussed Sandy Gao's proposal to revisit clause 4 of 3.4.6.1, but decided that if we were to attempt such a change, a new bug is warranted.

Thanks.
Comment 7 David Ezell 2010-11-10 17:13:22 UTC
The WG reported this bug as WORKSFORME on 2009-11-20.  We are closing this bug as requiring no futher work.  If there are issues remaining, you can reopen this
bug and enter a comment to indicate the problem.  Thanks very much for the
feedback.