Say you have an Order class with a bunch of properties as shown in listing
1. One of those properties is a collection of objects of the OrderItem class
shown in listing 2.
Listing 1: The Order class.
'________________ Order class ____________
'local variable(s) to hold property value(s)
Private mvarOrderId As Long 'local copy
Private mvarRequiredDate As Date 'local copy
Private mvarShipName As String 'local copy
'This is a collection of OrderDetail objects
Private mvarOrderDetails As Collection 'local copy
Public Property Set OrderDetails(ByVal vData As Collection)
Set mvarOrderDetails = vData
End Property
Public Property Get OrderDetails() As Collection
Set OrderDetails = mvarOrderDetails
End Property
Public Property Let ShipName(ByVal vData As String)
mvarShipName = vData
End Property
Public Property Get ShipName() As String
ShipName = mvarShipName
End Property
Public Property Let RequiredDate(ByVal vData As Date)
mvarRequiredDate = vData
End Property
Public Property Get RequiredDate() As Date
RequiredDate = mvarRequiredDate
End Property
Public Property Let OrderId(ByVal vData As Long)
mvarOrderId = vData
End Property
Public Property Get OrderId() As Long
OrderId = mvarOrderId
End Property
Listing 2: The OrderItem class.
'_____________________ OrderItem class ________________
'local variable(s) to hold property value(s)
Private mvarProductID As Long 'local copy
Private mvarUnitPrice As Double 'local copy
Private mvarQuantity As Integer 'local copy
Public Property Let Quantity(ByVal vData As Integer)
mvarQuantity = vData
End Property
Public Property Get Quantity() As Integer
Quantity = mvarQuantity
End Property
Public Property Let UnitPrice(ByVal vData As Double)
mvarUnitPrice = vData
End Property
Public Property Get UnitPrice() As Double
UnitPrice = mvarUnitPrice
End Property
Public Property Let ProductID(ByVal vData As Long)
mvarProductID = vData
End Property
Public Property Get ProductID() As Long
ProductID = mvarProductID
End Property
You’ll need to create a schema for the Order class if you’re going to serialize
Order objects to XML (possibly as parameter or return values from method calls
between tiers or as Web services). There are many ways you could serialize objects
of the Order class to XML. You should consider using an element to represent
each class property. This provides a consistent serialization technique and works
well with Web services.
Before we discuss the schema, take a look at the example XML document in listing
4 that represents a serialized Order object.
Listing 3: Example XML document with an Order object.
<Order>
<OrderId>2093324</OrderId>
<RequiredDate>2001-08-01</RequiredDate>
<ShipName>Yasser Shohoud</ShipName>
<OrderDetails>
<OrderItem>
<ProductID>53034</ProductID>
<Quantity>9</Quantity>
<UnitPrice>12.09</UnitPrice>
</OrderItem>
<OrderItem>
<ProductID>66090</ProductID>
<Quantity>12</Quantity>
<UnitPrice>10.09</UnitPrice>
</OrderItem>
<OrderItem>
<ProductID>56091</ProductID>
<Quantity>2</Quantity>
<UnitPrice>87.95</UnitPrice>
</OrderItem>
</OrderDetails>
</Order>
Listing 4 shows an example schema for the above document. This schema is the
XML-equivalent of the Order and OrderItem class definitions.
Listing 4: Example schema for Order and OrderItem.
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
elementFormDefault="unqualified">
<!-- this is the equivalent of the OrderItem class -->
<xsd:complexType name="OrderItemType">
<xsd:sequence>
<xsd:element name="ProductID" type="xsd:int"/>
<xsd:element name="Quantity" type="xsd:short"/>
<xsd:element name="UnitPrice" type="xsd:double"/>
</xsd:sequence>
</xsd:complexType>
<!-- this corresponds to the Order class -->
<xsd:complexType name="OrderType">
<xsd:sequence>
<xsd:element name="OrderId" type="xsd:int"/>
<xsd:element name="RequiredDate" type="xsd:date"/>
<xsd:element name="ShipName" type="xsd:string"/>
<xsd:element name="OrderDetails" type="OrderDetailsType"/>
<!-- the following is the equivalent of the OrderDetails
collection -->
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="OrderDetailsType">
<xsd:sequence>
<xsd:element name="OrderItem" type="OrderItemType"
maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<!-- this corresponds to the Order class -->
<xsd:element name="Order" type="OrderType"/>
</xsd:schema>
First, there’s a complex type called OrderItemType, which corresponds to the
OrderItem class. Within this type, there is a sequence of three elements, each
corresponds to a property of the OrderItem class. Here we have to map the intrinsic
VB types such as Long, Integer, and String to the corresponding XSD types. The
WSDL tutorial on this site has a table that shows the mapping between XSD and
VB types.
The next step is to define the OrderType. There’s again a sequence of elements that correspond to the properties of the Order class. For example, the RequiredDate property becomes an element called RequiredDate with the type xsd:date. The OrderDetails property is a collection of OrderItem objects. To define this, you create an element called OrderDetails. This element corresponds to the collection itself. To actually describe the type of objects in this collection, you need to specify that the OrderDetails element contains one ore OrderItem elements each of type OrderItemType (defined above). As you see in listing 3, this is done by creating a type called OrderDetailsType which contains a sequence of one or more OrderItem elements. To specify that there can be any number of OrderItem elements (any number of objects in the collection) we set the maxOccurs attribute to “unbounded”. There’s also a minOccurs attribute, which can specify the minimum number of times an element may occur. The default for both maxOccurs and minOccurs is 1, so if you don’t specify either of them it means the element appears exactly once.
Now that we have defined the OrderType, we are ready to declare the main element
of our document: The Order. The Order element is declared as a global element,
that is, it is not part of any type itself because it is the top-most element
in the document, also known as the document element.
This is just a simple example of how you can map VB classes (or User-Defined
Types) to XSD schemas. Once you’ve done a few of these, you’ll get the hang of
it. There’s a lot more you can do in XSD to make your validation tighter, let’s
take a look at some of that.
Comments