8.2. Concepts and Observations

Element types have very sophisticated, and often very confusing, capabilities. The next four sections attempt to expose some of the confusing issues surrounding element types. These sections cover global and local element types, substitution groups, blocking, nil elements (those with no value), and the use of namespaces vis-à-vis element types.

8.2.1. Global and Local Element Types

An element type is global or local. A global element type is a child of the schema element in the XML schema document. Otherwise, the element type is local to a complex type.

Listing 8.1 portrays the city element type introduced in Section 8.1 as local to the complex type addressType.

Listing 8.1. A Local Element Type (address.xsd)
<xsd:complexType name="addressType"> 
    <xsd:sequence> 
        <xsd:element ref="addressLine" 
                     minOccurs="1" 
                     maxOccurs="2"/> 
        <xsd:element name="city" type="xsd:string"/> 
        <xsd:element name="state" type="xsd:string"/> 
        <xsd:element name="country" 
                     type="xsd:string" 
                     fixed="US"/> 
        <xsd:element name="zip" type="xsd:string"/> 
        <xsd:element ref="effectiveDate"/> 
    </xsd:sequence> 
    <xsd:attribute ref="zipPlus4" use="optional"/> 
</xsd:complexType> 

8.2.2. Substitution Groups

A substitution group provides functionality that parallels derivation in that appropriate element types in a substitution group replace instantiable or non-instantiable element types. The parallel is that when an instantiable-derived type replaces a base type, substitutable element types replace base element types. The substitution of element types occurs in an XML instance or in an XML schema document. Listing 8.2 is a substitution group that provides a foundation for complete addresses.

Listing 8.2. The addressLine Substitution Group (address.xsd)
<xsd:element name="addressLine" 
             id="customerRecord.base.addressLine" 
             type="xsd:string" 
             abstract="true"> 
    <xsd:annotation> 
        <xsd:documentation xml:lang="en"> 
            The "addressLine" element type 
            is a base non-instantiable element 
            type whose structure type is 
            a built-in string datatype. 
        </xsd:documentation> 
    </xsd:annotation> 
</xsd:element>   

<xsd:element name="street" 
             type="xsd:string" 
             substitutionGroup="addressLine"> 
    <xsd:annotation> 
        <xsd:documentation xml:lang="en"> 
            Street is a substitution group 
            for addressLine.  This particular 
            substitution only substitutes the 
            name; there are no further restrictions. 
        </xsd:documentation> 
    </xsd:annotation> 
</xsd:element> 

<xsd:element name="POBox" 
             substitutionGroup="addressLine"> 
    <xsd:simpleType> 
        <xsd:annotation> 
            <xsd:documentation xml:lang="en"> 
                The POBoxType demonstrates that 
                a Substitution Group can have a 
                type that is derived from the 
                type used by the related 
                non-instantiable base element. 
            </xsd:documentation> 
        </xsd:annotation> 
        <xsd:restriction base="xsd:string"> 
            <xsd:maxLength value="10"/> 
            <xsd:pattern value="[0-9]+"/> 
        </xsd:restriction> 
    </xsd:simpleType> 
</xsd:element> 

<xsd:element name="pmb" 
             type="xsd:string" 
             substitutionGroup="addressLine"> 
    <xsd:annotation id="customerRecord.annotation.pmb"> 
        <xsd:documentation 
             source="http://new.usps.com/cgi-bin/uspsbv/scripts/content.jsp?D=13647" 
             xml:lang="en"> 
            A PMB is a "Private Mail Box" that is 
            provided by an entity other than the 
            U S Postal Service. 
           </xsd:documentation> 
        <xsd:documentation xml:lang="en"> 
            Developer Note:  Someone should probably 
            come up with a way to actually validate PMBs.  
           In fact, we should validate every <pmb/> 
           and <POBox/> element. 
        </xsd:documentation> 
        <xsd:appinfo 
            source="http://www.XMLSchemaReference.com/examples/java/extractJava"> 
            // A PMB is a "Private Mail Box" that is 
            // provided by an entity other than the 
            // U S Postal Service. 
            // -- create a class for the pmb 
            public class pmb 
                { 
           *     *     *     *     * 
                } 
         </xsd:appinfo> 
         <xsd:appinfo 
             source="http://www.XMLSchemaReference.com/examples/perl/extractPerl"> 
             # A PMB is a "Private Mail Box" that is provided 
             # by an entity other than the U S Postal Service. 
             # -- create a variable for the PMB 
             $pmb="" 
         </xsd:appinfo> 
     </xsd:annotation> 
</xsd:element> 

Substitution groups provide quite a bit of flexibility:

  • The head element type can be instantiable or non-instantiable.

  • The structure types associated with the element types in a substitution group can be different from each other. Substitutable element types can specify a structure type that is a derivation of the structure type associated with the head element type.

  • The structure types associated with the element types in a substitution group can be simple types or complex types. The only limitation is that the structure types are suitable derivations.

The XML representation of an element type whose structure type is the complex type addressType introduced in Listing 8.2 might look like the following element type:

<xsd:element name="address" type="addressType"/> 

Given the preceding element type, any of the following elements are valid in an XML instance. Note the inline replacement of addressLine with street, POBox, and pmb, respectively:

<address> 
    <street>123 Gravel Road</street> 
    <city>Nowheresville</city>   
    <state>OR</state> 
    <country>US</country> 
    <zip>97000</zip> 
    <effectiveDate></effectiveDate> 
</address> 

<address zipPlus4="20000-1234"> 
    <POBox>123</POBox> 
    <city>Small Town</city> 
    <state>VA</state> 
    <country>US</country> 
    <zip>20000</zip> 
    <effectiveDate>2001-02-14</effectiveDate> 
</address> 

<address> 
    <street>123 Main Street</street> 
    <pmb>12345</pmb> 
    <city>Metropolis</city> 
    <state>CO</state> 
    <country>US</country> 
    <zip>80000</zip> 
    <effectiveDate>2001-02-14</effectiveDate> 
</address> 

Frequently, the substitution occurs in the XML instance. The next example shows POBox substituted for the non-instantiable addressLine:

<address> 
    <POBox>123</POBox> 
    <city>Small Town</city> 
    <state>VA</state> 
    <country>US</country> 
    <zip>20000</zip> 
    <effectiveDate>2001-02-14</effectiveDate> 
</address> 

Listing 8.3 provides an XML representation for POBoxAddressType. This listing demonstrates substituting POBox for addressLine in an XML schema document that specifies a derived complex type.

Listing 8.3. Specifying a Substitution Group in a Derived Type (substGroup.xsd)
<xsd:complexType name="POBoxAddressType"> 
    <xsd:complexContent> 
        <xsd:restriction base="addressType"> 
            <xsd:sequence> 
                <xsd:element ref="POBox"  
                             minOccurs="1" 
                             maxOccurs="1"/> 
                <xsd:element name="city" type="xsd:string"/> 
                <xsd:element name="state" type="xsd:string"/> 
                <xsd:element name="country" 
                             type="xsd:string" 
                             fixed="US"/> 
                <xsd:element name="zip" type="xsd:string"/> 
                <xsd:element ref="effectiveDate"/> 
            </xsd:sequence> 
            <xsd:attribute ref="zipPlus4" use="optional"/> 
        </xsd:restriction> 
    </xsd:complexContent> 
</xsd:complexType> 

Tip

Sections 8.3.1.2 and 8.3.1.4 discuss how to prevent element type substitutions by specifying the block and final attributes.


8.2.3. Blocking Substitution

The block attribute of an element type, in conjunction with the block attribute of a complex type, restricts the ability to substitute, in an XML instance, specific members of a substitution group. Listing 8.4 is a complex set of substitution groups. The listing includes element types and the relevant structure types. The listing sets up the discussion surrounding the block attribute.

Tip

A solid understanding of complex types (see Chapter 11), including the block and final attributes (Sections 11.6.1.2 and 11.6.1.3, respectively), is valuable before attempting to use the block or final attributes of an element type.

Likewise, a solid understanding of substitution groups (see Section 8.2.2) is imperative.


There are three ways to impose blocking:

  • When the head of a substitution group blocks substitution, an XML instance cannot “replace” the head with another member of the substitution group.

  • When the head of a substitution group blocks extension, an XML instance cannot “replace” the head with another member of the substitution group whose structure type is an extension of the structure type associated with the head. In addition, an XML instance cannot specify a structure type, via xsi:type, that is derived—even indirectly—by extension from the structure type associated with the head.

  • When the head of a substitution group blocks restriction, an XML instance cannot “replace” the head with another member of the substitution group whose structure type is a restriction of the structure type associated with the head. In addition, an XML instance cannot specify a structure type, via xsi:type, that is derived—even indirectly—by restriction from the structure type associated with the head.

Note

A complex type can also specify blocking. The blocking is transitive. That is, when an element type’s structure type is a complex type, a block on that complex type effectively places a block on the element type.


In general, substitution groups are transitive. Listing 8.4 specifies two substitution groups: The first one contains the members ‘A’, ‘B’, and ‘C’, with ‘A’ being the head; the second one contains ‘C’ and ‘D’, with ‘C’ being the head. Transitively (through ‘C’), ‘B’, ‘C’, and ‘D’ are valid substitutions for ‘A’. Blocking, however, is not transitive. Specifically, a block on ‘C’ (or its structure type, ‘T3’), does not restrict the ability of ‘D’ to be a valid substitution for ‘A’.

Listing 8.4. Multiple Substitution Groups (substGroup.xsd)
<xsd:element name="A" type="T1" abstract="true" 
             block="restriction"> 
    <xsd:annotation> 
        <xsd:documentation> 
            Head of substitution group A. 
            An A element cannot appear in an XML 
            instance, since this element type is 
            abstract. 
        </xsd:documentation> 
    </xsd:annotation> 
</xsd:element> 
<xsd:element name="B" type="T1" substitutionGroup="A">  
    <xsd:annotation> 
        <xsd:documentation> 
        Member of substitution group A. 
        </xsd:documentation> 
    </xsd:annotation> 
</xsd:element> 
<xsd:element name="C" type="T3" substitutionGroup="A" 
             block="substitution"> 
    <xsd:annotation> 
        <xsd:documentation> 
            Member of substitution group A. 
            Head of substitution group C. 
            Blocking 'substitution' or 'extension' on C, 
            or blocking '#all' or 'extension' on T3, 
            would prevent D from being a valid substitution 
            for C.  D would, however, retain 
            its transitive ability to be a valid 
            substitution for A. 
        </xsd:documentation> 
    </xsd:annotation> 
</xsd:element> 
<xsd:element name="D" type="T4" substitutionGroup="C"> 
    <xsd:annotation> 
        <xsd:documentation> 
            Member of substitution group C. 
        </xsd:documentation> 
    </xsd:annotation> 
</xsd:element> 
<xsd:complexType name="T1"> 
    <xsd:sequence> 
        <xsd:element name="_1" type="xsd:token"/> 
    </xsd:sequence> 
</xsd:complexType> 
<xsd:complexType name="T2"> 
    <xsd:complexContent> 
        <xsd:extension base="T1"> 
            <xsd:sequence> 
                <xsd:element name="_2" type="xsd:token"/> 
            </xsd:sequence> 
        </xsd:extension> 
    </xsd:complexContent> 
</xsd:complexType> 
<xsd:complexType name="T3"> 
    <xsd:complexContent> 
        <xsd:extension base="T2"> 
            <xsd:sequence> 
                <xsd:element name="_3" type="xsd:token"/> 
            </xsd:sequence>   
        </xsd:extension> 
    </xsd:complexContent> 
</xsd:complexType> 
<xsd:complexType name="T4"> 
    <xsd:complexContent> 
        <xsd:extension base="T3"> 
            <xsd:sequence> 
                <xsd:element name="_4" type="xsd:token"/> 
            </xsd:sequence> 
        </xsd:extension> 
    </xsd:complexContent> 
</xsd:complexType> 

8.2.4. Element Type Instantiability

Normally, element types are instantiable. Furthermore, there is no way to “derive” one element type from another. The only utility of non-instantiable element types is in a substitution group: The head of the substitution group might be non-instantiable; the other members of the substitution group are instantiable, and can therefore “replace” the head.

Only element types and complex types can be explicitly non-instantiable. An XML instance cannot specify instances of an element type whose abstract attribute is ‘false’. Some element types are implicitly non-instantiable: An XML instance cannot specify instances of an element type whose structure type refers to a non-instantiable complex type.

Listing 8.2 demonstrates a non-instantiable addressLine, along with the appropriate substitutions street, POBox, and pmb. Note that the structure type associated with addressLine is xsd:string. The substitution street has the same structure type: xsd:string. The structure type associated with POBox, on the other hand, is a derivation of xsd:string.

Listing 8.4 is another example. Element type A is non-instantiable. All of the other element types in this listing are valid instantiable substitutions for A.

8.2.5. Nillable Element Types

An element type can specify a nillable attribute. When this occurs, the value of an element instance can be nil. A nil value is not the same as an empty value. For a string, “empty” means a string of zero length; nil means no string at all. Listing 8.5 specifies the nillable phoneNumber element type.

Listing 8.5. A Nillable Element Type (address.xsd)
<xsd:element name="phoneNumber" 
             type="xsd:string" 
             nillable="true"/> 

The XML instance must use the special nil attribute from the XML schema instance namespace to set the value to nil:

<phoneNumber xsi:nil="true"/> 

For clarity, a phoneNumber with an empty string has just a start-tag and an end-tag, or is an empty element:

<phoneNumber></phoneNumber> or </phoneNumber/> 

Note that the element that specifies the nil value—or an enclosing element—must declare the http://www.w3.org/2001/XMLSchema-instance namespace (see Chapter 7 ). The following declares this namespace tied to the ‘xsi’ qualifier, as used in the preceding XML instance with a nil value:

xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance 

Of course, an element whose element type permits a nil value can still have a value or content that is valid given the element type’s structure type. Listing 8.5 specifies xsd:string as the structure type of phoneNumber. The following element, with a string value, is a valid instance:

<phoneNumber>212-555-0000</phoneNumber> 

8.2.6. Element Types and Namespaces

This section discusses how an XML instance must specify namespaces for elements in order to locate the appropriate element types described throughout this chapter. Chapter 3 discusses how namespaces apply to the element types in the schema.

In an XML instance, the namespace of an element must match the namespace identified by the element type. Typically, element types do not specify the target namespace. Normally, the schema element specifies the target namespace. If a namespace is not specifically identified, and the target namespace is not specified, the element must be unqualified (that is, specified without a namespace).

In an XML instance, an element may be qualified (namespace specified) or unqualified (namespace not specified). An XML validator determines whether the namespace is required, by evaluating the following rules in order:

  • The element must be appropriately qualified when the element type specifies a form attribute (which has a value of ‘qualified’ or ‘unqualified’).

  • When the element type does not specify the form attribute, the elementformDefault attribute (which also has a value of ‘qualified’ or ‘unqualified’) of the schema element enclosing the element type determines whether the name of the element instance is qualified.

  • When the element type does not specify the form attribute, and the schema does not specify the elementformDefault attribute, the element must be unqualified. In other words, the default value for elementformDefault is ‘unqualified’.

Section 8.3.1.6, along with Listings 8.7 and 8.8, provides an example of how the form attribute of an element type works in conjunction with the elementformDefault attribute of the schema element.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.59.82.167