Creating Mixed-Content Elements

So far, the plain text in the documents that we've looked at in this chapter has been confined to the deepest elements in the document—that is, to elements that enclose no child elements, just text. However, as you know, you can also create elements that support mixed content, both text and other elements. You can create mixed-content elements with schemas as well as DTDs. In these elements, character data can appear at the same level as child elements.

Here's an example document that shows what mixed-content elements look like using the elements that we've declared in book.xsd; in this case, I'm creating a new element named <reminder> that encloses a reminder letter to a book borrower to return a book:

<?xml version="1.0">
<reminder>
    Dear <name>Britta Regensburg</name>:
        The book <bookTitle>Snacking on Volcanoes</bookTitle>
    was supposed to be out for only <maxDaysOut>14</maxDaysOut>
    days. Please return it or pay
    $<replacementValue>17.99</replacementValue>.
    Thank you.
</reminder>

This document uses both elements that we've defined before, character data, and the new <reminder> element. The <reminder> element is the one that has a mixed-content model; to declare it in a schema, I'll start by creating an anonymous new complex type inside the declaration for <reminder>:

<xsd:element name="reminder">
    <xsd:complexType>
    .
    .
    .
    </xsd:complexType>
 </xsd:element>

Recall that the <xsd:complexType> element has the content attribute with which you specify a content model; in this case, the content model is mixed:

<xsd:element name="reminder">
    <xsd:complexType content="mixed">
    .
    .
    .
    </xsd:complexType>
 </xsd:element>

Now all I have to do is to add the declarations for the elements that you can use inside the <reminder> element, like this:

<xsd:element name="reminder">
    <xsd:complexType content="mixed">
        <xsd:element name="name" type="xsd:string"/>
        <xsd:element name="bookTitle" type="xsd:string"/>
        <xsd:element name="maxDaysOut">
            <xsd:simpleType base="xsd:integer">
                <xsd:maxExclusive value="14"/>
            </xsd:simpleType>
        </xsd:element>
        <xsd:element name="replacementValue" type="xsd:decimal"/>
    </xsd:complexType>
 </xsd:element>

As you might recall from our discussion of DTDs, you can't constrain the order or number of child elements appearing in a mixed-model element. There's more power available when it comes to schemas, however—here, the order and number of child elements does indeed have to correspond to the order and number of child elements that you specify in the schema. In other words, even though DTDs provide only partial syntax specifications for mixed-content models, schemas provide much more complete syntax specifications.

In fact, the demands on XML processors that want to support schemas are great—including, for example, that they must implement the complete syntax for Perl-type regular expressions simply so that they can support the pattern facet. The upshot is that it might be a long time until a full implementation of schemas appears (if ever!).

elementOnly and textOnly Content Elements

Now that you know that you can use the content attribute of <xsd:complexType> to specify content models, such as empty and mixed, that raises this question: What model were we using when we used <xsd:complexType> without specifying a content model at all? For example, here's how the type transactionType is defined in book.xsd:

<xsd:element name="transaction" type="transactionType"/>

<xsd:complexType name="transactionType">
    <xsd:element name="Lender" type="address"/>
    <xsd:element name="Borrower" type="address"/>
    <xsd:element ref="note" minOccurs="0"/>
    <xsd:element name="books" type="books"/>
    <xsd:attribute name="borrowDate" type="xsd:date"/>
</xsd:complexType>

The default model for complex types is called elementOnly, which means that the type can include only elements. In other words, this type definition is the same as this one in which I explicitly make the type elementOnly:

<xsd:element name="transaction" type="transactionType"/>

<xsd:complexType name="transactionType" content="elementOnly">
    <xsd:element name="Lender" type="address"/>
    <xsd:element name="Borrower" type="address"/>
    <xsd:element ref="note" minOccurs="0"/>
    <xsd:element name="books" type="books"/>
    <xsd:attribute name="borrowDate" type="xsd:date"/>
</xsd:complexType>

Actually, I should say that the default complex type content model is elementOnly—except in one case. When you derive a complex type from a simple type, the content model is textOnly, not elementOnly. The textOnly content model specifies that the content of elements of this type is text, which means that the XML processor will not apply any syntax rules to that content.

You can also create textOnly content model types explicitly, as in this example, in which I'm creating a new version of the <bookID> element using the textOnly content model to allow it to support different indexing schemes (and, therefore, a different format for book IDs). Because different indexing schemes will have different formats for book ID values, I'm intentionally removing the syntax checking here:

<xsd:element name="bookID">
    <xsd:complexType content="textOnly">
        <xsd:attribute name="indexingScheme" type="xsd:string" />
    </xsd:complexType>
</xsd:element>

The result is that the <bookID> element may now contain any kind of text (but no elements), and the XML processor won't check it for syntax violations.

As a general rule, W3C suggests that you stay away from removing all syntax checks like this if you can avoid it. In fact, it's not difficult to use regular expressions to specify alternate pattern matches. This means that, in this case, you can still use a simple type based on string and can constrain the syntax of the book ID with the pattern facet.

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

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