Using the XML and Schema Designers
Visual Studio .NET gives you everything you need to effectively work with XML documents and XSD schemas. Using the Schema Designer, you can create XML schemas and link them to XML documents. Normally, a schema can be created directly from a database, but if you're not using a database and you need a relational way to represent data, you can build schemas directly in Visual Studio .NET. A schema contains all the information needed to describe any type of relational data that you're working with.To test this, create a new project named XML_vb or XML_cs, depending on the language you're using. After the project is open, right-click the project name in the Solution Explorer and select Add New Item from the contextual menu. Select XML Schema and change the name to EmployeesSchema as shown in Figure 12.2.
Figure 12.2. Adding the EmployeesSchema to your project.

After you click Open, the schema is added to your project and the Schema Designer is brought up. If you look at the Toolbox, you'll see that the controls in the Toolbox are now specifically related to designing XML schemas. Figure 12.3 is what you should see at this point.
Figure 12.3. The Schema Designer and XML Schema Toolbox tab.

Each item in the toolbox is a schema-specific object that you can drag onto the design surface in the designer to create the structure of your data. Table 12.1 gives you a break down of the items in the Toolbox and what each one can do.
Toolbox Item | Description |
---|---|
Element | Creates an Element that can be global, added to other Elements, added to Groups, or used to construct complexTypes. |
Attribute | Creates an attribute that can be global, added to Elements, or added to Groups. |
attributeGroup | Creates an attributeGroup that can be global, added to Elements, or used in the construct of complexTypes. |
complexType | Creates a complexType that you can add Elements, Attributes, attributeGroups, Anys, and anyAttributes to. |
simpleType | Creates a simpleType that you can add Facets to. |
Group | Creates groups that can be global, added to other Groups, Elements, or complexTypes. |
Any | Creates an Any element that can be added to Elements, complexTypes, or Groups. |
anyAttribute | Creates an anyAttribute element that can be added to Elements, attributeGroups, or complexTypes. |
Facet | Creates a Facet that can be added to a simpleType. A facet is used to further restrict the definition of a simple type. |
Key | Launches the Edit Key dialog box that's used to create keys when added to an element. |
Relation | Launches the Edit Relation dialog box that's used to define relationships between elements. You can use this to create one-to-many relationships in XML schemas and datasets. |
Creating the Employees Schema
The goal of this section is to guide you through the creation of a schema using the designer, to link the schema to an XML document, and use the XML document and schema in an application.You've already added an XSD file to your application and named it EmployeesSchema. Now, you need to use the items in the XML Schema toolbox to create the types that make up the XML document.
Using Simple Types to Create the ZipCode Field
The first step is to create a simpleType named ZipCode. The ZipCode type uses a regular expression syntax to create a constraint for the field. To do this:- .
You've now created a simple type named ZipCode that uses a regular expression pattern to enforce a rule that says that anything entered into this field should be five numeric positive numbers. If you switch to the XML view by clicking the XML button on the lower left of the screen, you'll see that the definition of the ZipCode type looks something like this:
You learned about validation controls in ASP.NET on Day 5, "Writing ASP.NET Applications." RegularExpressionValidator controls use regular expression syntax to generate the client-side JavaScript that enforces the validation rules for the server controls associated with the validation control. In schemas, you create a Facet type with a pattern to implement any type of pattern for a data type. This is almost identical to using a constraint in a SQL Server table.
<xs:simpleType name="ZipCode">
<xs:restriction base="xs:positiveInteger">
<xs:pattern value="\d{5}" />
</xs:restriction>
</xs:simpleType>
Tip
To learn more regular expressions, create a new ASP.NET application and add a RegularExpressionValidator control to the Web Form. In the Properties dialog box for the control, select the ValidationExpression property to view the syntax for the various options. For example, to validate an Internet email address, the regular expression syntax is "\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*".Creating the Address Complex Type
Now you create the Address complexType to hold address information for the Employees. This is a complexType because in the schema, it can contain any of the types listed in Table 12.1. If you're in XML view, click the Schema button to return to the Schema Designer. To create the Address type, follow these steps:- Drag a complexType from the Toolbox onto the designer.
- Change the name from complexType1 to Address. Don't select a data type from the second column.
- Click to the next row, and select element from the drop-down list in the first column. In the second column, type Name for the Element name, and select String as the data type from the drop-down list in the third column.
- Click to the next row, and select element from the drop-down list in the first column. In the second column, type Street for the Element name, and select String as the data type from the drop-down list in the third column.
- Click to the next row, and select element from the drop-down list in the first column. In the second column, type State for the Element name, and select string as the data type from the drop-down list in the third column.
- Click to the next row, and select element from the drop-down list in the first column. In the second column, type Zip for the element name, and select ZipCode as the data type from the drop-down list in the third column. The Zip element now follows the rules you've defined for the ZipCode simple type.
Next you must create the main elements that make up the data for each customer. The ZipCode and Address are basically data types that are used for each Employee. If you compare this to tables in a database, the Address type would be a child table to an Employee parent table.
Creating the Main Employee Elements
To create the main elements for the Employee schema, follow these steps:- Drag an element type from the Toolbox onto the design surface.
- Change the name from element1 to Employee. Leave the Data Type column blank. This will be the main Employee element for each record in the XML document.
- Click to the next row, and select Element from the drop-down list in the first column. In the second column, type Email for the element name, and select String as the data type from the drop-down list in the third column.
- Click to the next row, and select element from the drop-down list in the first column. In the second column, type Password for the element name, and select String as the data type from the drop-down list in the third column.
- Click to the next row, and select element from the drop-down list in the first column. In the second column, type HomeAddress for the element name, and select Address as the data type from the drop-down list in the third column. At this point, notice that the Address complex type you created earlier is connected to the HomeAddress element you just added. You can see that the hierarchy of the XML document is starting to take shape.
- Click to the next row, and select element from the drop-down list in the first column. In the second column, type OtherAddress for the element name, and select Address as the data type from the drop-down list in the third column. Again, an Address type is connected to the OtherAddress element just added.
You've now defined the elements to hold the employee data and employee address information. If you switch to the XML view of the designer, you'll see something like this:
The last step in creating the schema is to add the root element. To be well-formed XML, all XML documents must have a root element.
<xs:simpleType name="ZipCode">
<xs:restriction base="xs:positiveInteger">
<xs:pattern value="\d{5}" />
</xs:restriction>
</xs:simpleType>
<xs:complexType name="Address">
<xs:sequence>
<xs:element name="Name" type="xs:string" />
<xs:element name="Street" type="xs:string" />
<xs:element name="State" type="xs:string" />
<xs:element name="Zip" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:element name="Employee">
<xs:complexType>
<xs:sequence>
<xs:element name="Email" type="xs:string" />
<xs:element name="Password" type="xs:string" />
<xs:element name="HomeAddress" type="Address" />
<xs:element name="OtherAddress" type="Address" />
</xs:sequence>
</xs:complexType>
</xs:element>
Adding the Root Element to the EmployeeSchema
There is no root element type in the toolbox. The root element of any XML document is just another element, so to add the root element to the schema:- Figure 12.4.
Figure 12.4. The EmployeesSchema XML schema.

If you switch to the XML view of the designer, you'll see the XML schema definition for the EmployeesSchema that Figure 12.5 depicts. Using the designer to create XML schemas is obviously much easier than hand-coding the complete schema shown in Figure 12.5.
Figure 12.5. The XML view of EmployeesSchema.

Next, you need to associate the schema with an XML document.
Adding the Employees XML Document
To add the XML document that uses the EmployeesSchema, right-click on your project name in the Solution Explorer and select Add New Item from the contextual menu. Select XML File from the Add Item dialog, and name it Employees as Figure 12.6 demonstrates.
Figure 12.6. Adding the Employees XML file.

After the Employees.xml file is added, you must associate it with the EmployeesSchema. To do so, right-click the XML file in the XML Designer and select Properties from the contextual menu. When the Properties dialog pops up, you can select the schema from Target Schemas drop-down list, as Figure 12.7 demonstrates. After you select EmployeesSchema, click the OK button to close the Properties dialog box.
Figure 12.7. Associating EmployeesSchema with the Employees XML document.

Now that the Employees XML file has a schema, the XML Designer in Visual Studio .NET shows its true power. If you click the Data button in the lower-left corner of the designer to switch to the Data view, you can see the hierarchy of data that the schema has set up.From this point, you can add, edit, and delete records just as if this were a regular database table. Figure 12.8 is the Data view after adding an Employee record. Notice that HomeAddress and OtherAddress are children to the Employee main element.
Figure 12.8. Adding data to the XML file using the Data view.

Next, you can write an application that actually reads and writes data from this XML file.
Using the Employees XML File in an Application
Earlier you learned that the DataSet class can natively read and write XML files using XmlReaders and XmlWriters. Table 12.2 lists the XML-specific methods that you can use when working with XML files and schemas with the DataSet class.
Method Name | Description |
---|---|
GetXml | Returns the XML representation of the data stored in the DataSet. |
GetXmlSchema | Returns the XSD schema for the XML representation of the data stored in the DataSet. |
InferXmlSchema | Infers the XML schema from the specified TextReader or file into the DataSet. |
ReadXml | Reads an XML schema and data into the DataSet. |
ReadXmlSchema | Reads an XML schema into the DataSet. |
WriteXml | Writes XML data and, optionally, the schema, from the DataSet. |
WriteXmlSchema | Writes the DataSet structure as an XML schema. |
Figure 12.9. The TestXmlSchema form after arranging controls.

Double-click the Load XML File button to get to the click event for the control. Add the code in Listing 12.2 to handle the click events for the three buttons.
Listing 12.2 Code for the TestXmlSchema Form

Dim ds As New DataSet("MyFile")
Private Sub LoadXMLFile_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles LoadXMLFile.Click
' Read the XML Schema into the DataSet
ds.ReadXmlSchema("../EmployeesSchema.xsd")
' Read the XML file into the DataSet
ds.ReadXml("../Employees.xml")
' Bind the grid to the DataSet
DataGrid1.DataSource = ds
End Sub
Private Sub DisplaySchema_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles DisplaySchema.Click
' Call the GetXmlSchema method to display the loaded schema
MessageBox.Show(ds.GetXmlSchema)
End Sub
Private Sub SaveXML_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles SaveXML.Click
' Write out the data in the grid to a new XML file
ds.WriteXml("NewXmlFile.xml")
End Sub

The code is straightforward based on what you already know about DataSets and XML files. You simply write code to load the XML file and schema, and then write the data in the grid to a new file after you've changed information in the grid. The click event that calls the GetXmlSchema method displays the schema for the DataSet. If you click this before loading the XML and schema into the grid, you'll see that a default schema is still available when there's nothing in the DataSet.Run the application by pressing the F5 key. After the application starts, add some data to the rows in the grid. You'll notice the hierarchy of the XML schema is completely maintained; the DataGrid looks exactly as it did in the XML Designer. Figure 12.10 is what the TextXmlSchema form should look like at runtime.
private DataSet ds = new DataSet();
private void LoadXML_Click(object sender, System.EventArgs e)
{
// Read the XML Schema into the DataSet
ds.ReadXmlSchema(@"../EmployeesSchema.xsd");
// Read the XML file into the DataSet
ds.ReadXml(@"../Employees.xml");
// Bind the grid to the DataSet
dataGrid1.DataSource = ds;
}
private void DisplaySchema_Click(object sender, System.EventArgs e)
{
// Call the GetXmlSchema method to display the loaded schema
MessageBox.Show(ds.GetXmlSchema());
}
private void SaveXML_Click(object sender, System.EventArgs e)
{
// Write out the data in the grid to a new XML file
ds.WriteXml(@"NewXmlFile.xml");
}
Figure 12.10. Running the TextXmlSchema application.

If you add a new row to the grid, add an OtherAddress but not a HomeAddress. You'll test XML validation in the Visual Studio .NET XML designer. Also, when you enter data into the grid, attempt to add an invalid ZipCode, such as alphanumeric characters. You'll notice that the DataGrid enforces the rules of the schema, and reverts to the previous value in the grid if you try to enter data that disagrees with the schema definition.After adding some data, click the Save Data To XML File button. In the Bin directory of your project, you should see the NewXmlFile.Xml file that you just saved.
Note
If the Bin directory isn't visible, click the Show All Files button on the Solution Explorer toolbar. You might also have to click the Refresh button on the Solution Explorer toolbar to see the NewXmlFile.xml file.Double-click the NewXmlFile.Xml to open it in the designer. You should see the new records that you added to the DataGrid. To validate the XML file against the EmployeesSchema XSD file, select the Validate XML Data option from the XML menu. The XML file is validated against the schema. If there are any errors, which there should be, they appear in the Task List window just as any other build error would. Figure 12.11 shows you what the errors should look like if you didn't enter a HomeAddress for an employee.Figure 12.11. Results of validating the XML file against the schema.
