The most basic thing to understand about XML schemas is the concept of using simple and complex types, and how they relate to declaring elements. In schemas, unlike DTDs, you specify the type of the elements you declare. That means that the first step in declaring elements is to make sure you have the types you wantand that often means defining new complex types. Complex types can enclose elements and have attributes, and simple types cannot do either. You can find the simple types built into XML schemas in Table 5-3. (When you specify these types in schemas, bear in mind that you'll preface them with the W3C schema prefix, usually xsd: .) Table 5-3. Simple Types Built into XML Schema
You create new complex types using the <xsd:complexType> element in schemas. A complex type definition itself usually contains element declarations, references to other elements, and attribute declarations. You declare elements with the <xsd:element> element, and you declare attributes with the <xsd:attribute> element. As in DTDs, element declarations specify the syntax of an element. In schemas, though element declarations can specify the elements' type as well. You can specify the type of attributes as well. Here's an example from ch05_07.xsd. In this case, I'm declaring a complex type named address , which holds the elements that make up a person's address, in this order. (The <xsd:sequence> element indicates that this is the order the contained elements should appear in. If you don't want to specify the order, use an element such as <xsd:all> insteadsee "Creating all Groups," later in this chapter.) <xsd:complexType name="address"> <xsd:sequence> <xsd:element name="name" type="xsd:string"/> <xsd:element name="street" type="xsd:string"/> <xsd:element name="city" type="xsd:string"/> <xsd:element name="state" type="xsd:NMTOKEN"/> </xsd:sequence> <xsd:attribute name="phone" type="xsd:string" use="optional"/> </xsd:complexType> I'll use address as the type of the <Lender> and <Borrower> elements so that I can store the address of the books' lender and borrower. That declaration looks like this: <xsd:complexType name="transactionType"> <xsd:sequence> <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:sequence> <xsd:attribute name="borrowDate" type="xsd:date"/> </xsd:complexType> In the address type, I'm indicating that any element of this type must have four elements and one attribute. Those elements are <name> , <street> , <city> , and <state> ; the attribute is phone . Note how the declarations for these elements set their data types as well: <name> , <street> , and <city> must all be of type xsd:string , and the <state> element must be of type NMTOKEN . The attribute phone must be of type xsd:string as well. The definition of the address complex type contains only declarations based on the simple type xsd:string . On the other hand, complex types can themselves contain elements that are based on complex types. You can see how this works in the transactionType , which is the type of ch05_06.xml's root element, <transaction> . In this case, two of the elements, <Lender> and <Borrower> , are themselves of the address type. Note that the transactionType type also includes an attribute, borrowDate , which is of the simple type xsd:date . Attributes are always of a simple type because attributes can't have internal content. After you've defined a new type, you can declare new elements of that type. For example, after declaring the transactionType , you can declare the <transaction> element, which is the root element of the document, to be of that type, like this: <xsd:element name="transaction" type="transactionType"/> <xsd:complexType name="transactionType"> <xsd:sequence> <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:sequence> <xsd:attribute name="borrowDate" type="xsd:date"/> </xsd:complexType> So far, then, we've gotten an overview of how to create new element and attribute declarations. You use <xsd:element> and <xsd:attribute> elements and set the type attribute of those elements to the type you want. If you want to use a complex type, you'll have to create it, and you do that with the <xsd:complexType> element (we'll see how to create simple types in a few pages). Now take a look at the declaration for the <note> element in the transactionType type: <xsd:complexType name="transactionType"> <xsd:sequence> <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:sequence> <xsd:attribute name="borrowDate" type="xsd:date"/> </xsd:complexType> Here, I'm not declaring a new element. Instead, I'm including an already existing element by referring to it. That is to say, the <note> element already exists because we've declared it separately like this: <xsd:complexType name="transactionType"> <xsd:sequence> <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:sequence> <xsd:attribute name="borrowDate" type="xsd:date"/> </xsd:complexType> <xsd:element name="note" type="xsd:string"/> Using the ref attribute lets you include an element that has already been defined in a complex type definition. However, you can't just include any element by referencethe element you refer to must have been declared globally, which means that it itself is not part of any other complex type. A global element or attribute declaration appears as an immediate child element of the <xsd:schema> element. When you declare an element or attribute globally, it can be used in any complex type. Using the ref attribute in this way is a powerful technique because it lets you avoid redefining elements that already exist globally. Now I'll take a look at how to specify how many times elements can occur in a complex type. |