Re: Deep Extension

Hi Joseph,

> One of the derived types, EncrypteKeyType is a straightfoward
> extension, I'm adding children and attributes to the EncryptedType.
> *However*, the other type is tricky. EncryptedDataType needs nothing
> more complex than an Nonce attribute added to its CipherData. Simple
> requirement, but complex in practice I'm finding.

When you add an attribute to an element, you change its type. So what
you're saying is that the type of CipherData in EncryptedDataType is
an extension of the type of CipherData in the abstract EncryptedType.

When you extend a type, the start of the content model of the new type
has to be exactly the same as the start of the base type. That means
you can't change the type of an element from the base type when you
derive by extension.

The only way you can change the type of an element from a base type is
by restriction. If you derive EncryptedDataType from EncryptedType by
restriction, you could change the type of the CipherData element in
EncryptedDataType, but to do so you have to change the type *by
restriction*.

So you have to turn it around:

 - create a general CipherDataType type that allows both the content
   that you already have and the new Nonce attribute that you want to
   have on the CipherData element in the EncryptedDataType type.

   <xs:complexType name="GeneralCipherDataType">
     <xs:choice>
       <xs:element name="CipherValue" type="xs:base64Binary" />
       <xs:element ref="xenc:CipherReference" />
     </xs:choice>
     <xs:attribute name="Nonce" type="xs:integer" />
   </xs:complexType>

 - derive a type from this general CipherDataType type that doesn't
   allow the Nonce attribute.
   
   <xs:complexType name="CipherDataType">
     <xs:complexContent>
       <xs:restriction base="GeneralCipherDataType">
         <xs:choice>
           <xs:element name="CipherValue" type="xs:base64Binary" />
           <xs:element ref="xenc:CipherReference" />
         </xs:choice>
         <xs:attribute name="Nonce" type="xs:integer"
                       use="prohibited" />
       </xs:restriction>
     </xs:complexContent>
   </xs:complexType>

 - make the CipherData element declared in the EncryptedType complex
   type be of the general CipherDataType.

   <xs:complexType name="EncryptedType" abstract="true">
     <xs:sequence>
       <xs:element name="CipherData"
                   type="xenc:GeneralCipherDataType" />
       <xs:element ... />
     </xs:sequence>
   </xs:complexType>

 - the EncryptedDataType is now exactly the same as the EncryptedType,
   so you just need:

   <xs:complexType name="EncryptedDataType">
     <xs:complexContent>
       <xs:extension base="xenc:EncryptedType" />
     </xs:complexContent>
   </xs:complexType>

 - the EncryptedKeyType needs to be derived in two stages, first by
   restriction to get rid of the Nonce attribute by making the
   CipherData element be of the CipherDataType instead of the
   GeneralCipherDataType:

   <xs:complexType name="EncryptedTypeNoNonce">
     <xs:complexContent>
       <xs:restriction base="xenc:EncryptedType">
         <xs:sequence>
           <xs:element name="CipherData"
                       type="xenc:CipherDataType" />
           <xs:element ... />
         </xs:sequence>
       </xs:restriction>
     </xs:complexContent>
   </xs:complexType>

 - then by extension to add the new elements that you want:

   <xs:complexType name="EncryptedKeyType">
     <xs:complexContent>
       <xs:extension base="xenc:EncryptedType">
         ...
       </xs:extension>
     </xs:complexContent>
   </xs:complexType>

Of course you might want to change the names of the complex types so
that they make more sense, to something like:

GeneralEncryptedType (rather than EncryptedType)
 - EncryptedDataType
 - EncryptedType     (rather than EncryptedTypeNoNonce)
   - EncryptedKeyType

Another possibility is to make the EncryptedDataType the top of the
hierarchy (since it's exactly the same as the GeneralEncryptedType):

EncryptedDataType
 - EncryptedType (derived by restriction, prohibiting the Nonce attr)
   - EncryptedKeyType (derived by extension)

But I imagine that you want both the EncryptedDataType and the
EncryptedKeyType to be derived from the same named base type.
   
I hope that helps,

Jeni

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

Received on Thursday, 29 November 2001 06:04:13 UTC