Add Missing Elements to the Root Element
A significant flaw may have been noticed in the final structure we arrived at in the
last section – when building documents using this DTD, there's no place to add a
<Customer> element. It's not the root element of the document, and
it doesn't appear in any of the element content models of any of the other elements in
the structure. This is because it is only pointed to, not contained.
Elements that turn out to only be referenced by IDREF(S) need to be added as allowable
element content to the root element of the DTD. Then, when creating the document, the
orphaned elements are created within the root element and then pointed to, where
appropriate.
Applying this rule to our example, we see that we are missing the <Customer>
and <Part> elements. Adding these as allowable structural content to
our root element gives us:
<!ELEMENT SalesData (Invoice*, Customer*, Part*, MonthlyTotal*)>
<!ATTLIST SalesData
Status (NewVersion | UpdatedVersion | CourtesyCopy) #REQUIRED>
<!ELEMENT Invoice (LineItem*)>
...
Rule 10: Add Missing Elements.
For any element that is only pointed to in the structure created so far, add
that element as allowable element content of the root element. Set the cardinality
suffix of the element being added to *.
Discard Unreferenced ID attributes
Finally, we need to discard those ID attributes that we created in Rule 5
that do not have IDREF(S) pointing to them. Since we created these attributes in
the process of building the XML structures, discarding them if they are not
used does not sacrifice information, and saves developers the trouble of
generating unique values for the attributes.
Rule 11: Remove Unwanted ID Attributes.
Remove ID attributes that are not referenced by IDREF or IDREFS attributes
elsewhere in the XML structures.
Applying Rule 11 to our example gives us our final structure. On
review, the InvoiceID, LineItemID, MonthlyPartTotalID,
MonthlyTotalID, and MonthlyCustomerTotalID
attributes are not referenced by any IDREF or IDREFS attributes.
Removing them, we arrive at our final structure:
<!ELEMENT SalesData (Invoice*, Customer*, Part*, MonthlyTotal*)>
<!ATTLIST SalesData
Status (NewVersion | UpdatedVersion | CourtesyCopy) #REQUIRED>
<!ELEMENT Invoice (LineItem*)>
<!ATTLIST Invoice
InvoiceNumber CDATA #REQUIRED
TrackingNumber CDATA #REQUIRED
OrderDate CDATA #REQUIRED
ShipDate CDATA #REQUIRED
ShipMethod (USPS | FedEx | UPS) #REQUIRED
CustomerIDREF IDREF #REQUIRED>
<!ELEMENT Customer EMPTY>
<!ATTLIST Customer
CustomerID ID #REQUIRED
Name CDATA #REQUIRED
Address CDATA #REQUIRED
City CDATA #REQUIRED
State CDATA #REQUIRED
PostalCode CDATA #REQUIRED>
<!ELEMENT Part EMPTY>
<!ATTLIST Part
PartID ID #REQUIRED
PartNumber CDATA #REQUIRED
Name CDATA #REQUIRED
Color CDATA #REQUIRED
Size CDATA #REQUIRED>
<!ELEMENT MonthlyTotal (MonthlyCustomerTotal*, MonthlyPartTotal*)>
<!ATTLIST MonthlyTotal
Month CDATA #REQUIRED
Year CDATA #REQUIRED
VolumeShipped CDATA #REQUIRED
PriceShipped CDATA #REQUIRED>
<!ELEMENT MonthlyCustomerTotal EMPTY>
<!ATTLIST MonthlyCustomerTotal
VolumeShipped CDATA #REQUIRED
PriceShipped CDATA #REQUIRED
CustomerIDREF IDREF #REQUIRED>
<!ELEMENT MonthlyPartTotal EMPTY>
<!ATTLIST MonthlyPartTotal
VolumeShipped CDATA #REQUIRED
PriceShipped CDATA #REQUIRED
PartIDREF IDREF #REQUIRED>
<!ELEMENT LineItem EMPTY>
<!ATTLIST LineItem
Quantity CDATA #REQUIRED
Price CDATA #REQUIRED
PartIDREF IDREF #REQUIRED>
Contents |