Home > Articles > Web Services > XML

  • Print
  • + Share This
  • 💬 Discuss
This chapter is from the book

This chapter is from the book

18.7 -Example: XML Schema Tree

Now that we have examined some of the features of the Microsoft XML Core Services, we can pull these concepts together in a single application. To illustrate the XML Schema features of MSXML, you can build a simple tool in Visual Basic to examine an XML schema document and validate documents against it.

Before building the project, you must have already installed the MSXML 4.0 components on the development machine. You can find these components, which are both free and redistributable, at the Microsoft Developer Network site, specifically at:

http://msdn.microsoft.com/downloads/sample.asp?url=/MSDN-FILES/027/ 001/766/msdncompositedoc.xml

After you have downloaded and executed the installation, you can develop applications by using MSXML.

The XML Schema Tree sample was created in Visual Basic 6.0 as a Standard Executable project. The project has a single form, SchemaTreeForm, that provides menus and displays the schema information. The sample code can be downloaded from

http://www.XMLSchemaReference.com/examples/Ch18. 

Figure 18.4 shows the design-time view of the SchemaTreeForm. It consists of a menu, a tree view, an image list, and a common dialog control.

To create this project, first select a new Standard Executable. Next you must include the necessary components to build the project. The project requires three additional libraries: MSXML 4.0, the Microsoft Common Dialog Control, and the Microsoft Windows Common Controls. The Microsoft Common Dialog Control contains the common file Open/Save dialog box used in Windows applications, and the Common Controls library holds both the tree view and the image list controls. To load these into your application, you must configure the project file to use them. You can add MSXML support to this project just as shown in Figure 18.2. Under the Visual Basic menu, select the Project menu, and then select References to add the MSXML 4.0 components. Add the other two libraries in a similar fashion: From the Project\Components check list, select both the Microsoft Common Dialog Control and the Microsoft Windows Common Controls.

Figure 18.4 FIGURE 18.4 XML Schema Tree form at design time.


Depending on the system you are running, you might have different versions of the Common Dialog and Common Controls libraries. The feature set used in this application is common to all versions of these libraries, so just select the ones available on your machine.

Now that you have configured your project to use all the necessary libraries, you can examine the application. The tree view, treeSchema, displays the schema contents whenever the File\Open Schema menu item is selected. The application fills the tree with items for the various element types, attribute types, and other parts of the XML schema. The other menu items let users select an XML document to be validated against the loaded schema, by using either the DOM or SAX2 features. The common dialog box allows users to browse for files, and the image list provides icons for the tree view items.

The code for the Schema Tree application is shown in the following listings. Listing 18.12 begins the code for the form shown in Figure 18.4. Loading and selecting an XML schema file and resizing the windows are handled here in code.

LISTING 18.12 SchemaTreeForm.frm Code Part 1

'SchemaTreeForm.frm
'
'Tree view representation of an XML schema using MSXML and SOM

Private m_schemaCache As XMLSchemaCache40

Private Sub Form_Load()
    status.SimpleText = "No schema"
    Set m_schemaCache = Nothing
End Sub

Private Sub Form_Resize()
    treeSchema.Move 0, 0, Me.ScaleWidth, Me.ScaleHeight
End Sub

Private Sub IDM_FILEEXIT_Click()
    Set m_schemaCache = Nothing
    Unload Me
End Sub

Private Sub IDM_FILEOPEN_Click()
On Error GoTo OpenErr
    status.SimpleText = "Working.."
    treeSchema.Nodes.Clear
    Set m_schemaCache = New XMLSchemaCache40
    Dim docSchema As DOMDocument40
    Dim schema As ISchema
    Dim strTargetNS As String
    Set docSchema = New DOMDocument40
    docSchema.async = False
    docSchema.validateOnParse = False
    Dim strFile As String
    filedlg.ShowOpen
    If filedlg.FileName = "" Then Exit Sub
    strFile = filedlg.FileName
    If (docSchema.Load(strFile)) Then
        status.SimpleText = "Loaded " & strFile
    Else
        Dim docError As IXMLDOMParseError
        MsgBox docError.reason, vbCritical, "Schema Tree"
        Exit Sub
    End If
    Dim elemDoc As IXMLDOMElement
    Dim attr As IXMLDOMAttribute
    Set elemDoc = docSchema.documentElement
    Set attr = elemDoc.getAttributeNode("targetNamespace")
    strTargetNS = ""
    If attr Is Nothing = False Then
        strTargetNS = attr.Value
    End If
    m_schemaCache.Add strTargetNS, docSchema
    Set schema = m_schemaCache.getSchema(strTargetNS)
    FillSchemaTree schema, treeSchema
    Exit Sub
OpenErr:
    MsgBox Err.Description, vbCritical, "Schema Tree"
    status.SimpleText = "No schema"
    Set m_schemaCache = Nothing
    Exit Sub
End Sub

Listing 18.13 continues the form code. The subroutine FillSchemaTree uses the SOM to traverse the contents of the XML schema and load each set of parts into the tree view. Beginning with the ISchema interface, this routine accesses the properties of ISchema and walks the returned ISchemaItemCollection interfaces.

LISTING 18.13 SchemaTreeForm.frm Code Part 2

'Fill a standard TreeView with a tree representation of an XML
' Schema as returned by the MSXML SOM ISchema interface
'This code currently only loads the list of elements, 
' attributes, and types
Public Sub FillSchemaTree(schema As ISchema, tree As TreeView)
    If schema Is Nothing Then Exit Sub
    If tree Is Nothing Then Exit Sub
    tree.Nodes.Clear
    Dim nodeRoot As Node
    Dim nodeCurr As Node
    Dim strRoot As String
    strRoot = schema.Name
    If strRoot = "" Then strRoot = "<schema>"
    Set nodeRoot = tree.Nodes.Add(,,, strRoot, 1)
    'Elements
    Dim nodeElemGroup As Node
    Set nodeElemGroup = tree.Nodes.Add(nodeRoot.Index, _
     tvwChild, , "<elements>", 2)
    Dim elem As ISchemaElement
    For Each elem In schema.elements
        Dim nodeElem As Node
        Set nodeElem = tree.Nodes.Add(nodeElemGroup.Index, _
         tvwChild,, elem.Name, 2)
    Next elem

    'Attributes
    Dim nodeAttrGroup As Node
    Set nodeAttrGroup = tree.Nodes.Add(nodeRoot.Index, _
     tvwChild,, "<attributes>", 3)

    Dim attr As ISchemaAttribute
    For Each attr In schema.Attributes
    Dim nodeAttr As Node
    Set nodeAttr = tree.Nodes.Add(nodeAttrGroup.Index, _
     tvwChild,, attr.Name, 3)
    Next attr

    'Types
    Dim nodeTypeGroup As Node
    Set nodeTypeGroup = tree.Nodes.Add(nodeRoot.Index, _
     tvwChild,, "all types", 5)

    Dim nodeSimpleTypeGroup As Node
    Set nodeSimpleTypeGroup = tree.Nodes.Add(_
     nodeTypeGroup.Index, tvwChild,, "simple types", 5)

    Dim nodeComplexTypeGroup As Node
    Set nodeComplexTypeGroup = tree.Nodes.Add(_
     nodeTypeGroup.Index, tvwChild,, "complex types", 4)

    Dim t As ISchemaType
    For Each t In schema.types
        Dim nodeType As Node
        If t.itemType = SOMITEM_COMPLEXTYPE Then
            Dim ct As ISchemaComplexType
            Set ct = Nothing
            Set ct = t
            Set nodeType = tree.Nodes.Add(_
             nodeComplexTypeGroup.Index, tvwChild,,_
             t.Name, 4)
        End If
      
        If t.itemType = SOMITEM_SIMPLETYPE Then
            Set nodeType = tree.Nodes.Add(_
             nodeSimpleTypeGroup.Index, tvwChild,, t.Name, 5)
        End If
    Next t

    'Expand the schema element
    nodeRoot.Expanded = True
End Sub

Listing 18.14 shows the last portion of form code: the menu handlers for the validation. These routines handle the validation by DOM or SAX, respectively. For both validations, the XMLSchemaCache40 is used to select the schemas in question. The DOM validation uses the schemas property of the DOMDocument40, whereas the SAX2 validation uses the getProperty method of SAXXMLReader40. In addition, in both cases you must make sure validation is active. When using the DOM, you activate validation using the validateOnParse property, and when using SAX, the getFeature method is used.

LISTING 18.14 SchemaTreeForm.frm Code Part 3

Private Sub IDM_FILEVALIDATEDOM_Click()
    Dim doc As DOMDocument40
    Dim docError As IXMLDOMParseError
    If m_schemaCache Is Nothing Then
        MsgBox "No schema is loaded", vbCritical, "Schema Tree"
        Exit Sub
    End If
    Set doc = New DOMDocument40
    doc.async = False
    doc.validateOnParse = True
    Set doc.schemas = m_schemaCache
    Dim strFile As String
    filedlg.ShowOpen
    If filedlg.FileName = "" Then Exit Sub
    strFile = filedlg.FileName
    Dim b As Boolean
    b = doc.Load(strFile)
    Set docError = doc.parseError
    If (docError.errorCode = 0) Then
        MsgBox _
         "The document is valid according to the schema.", _
         vbOKOnly, "Schema Tree"
    Else
        MsgBox docError.reason, vbCritical, "Schema Tree"
    End If
    Set doc = Nothing
End Sub

Private Sub IDM_FILEVALIDATESAX_Click()
On Error GoTo SaxErr
    Dim sax As SAXXMLReader40
    If m_schemaCache Is Nothing Then
        MsgBox "No schema is loaded", vbCritical, "Schema Tree"
        Exit Sub
    End If
    Set sax = New SAXXMLReader40
    Dim handler As SAXTest
    Set handler = New SAXTest
    Dim strFile As String
    filedlg.ShowOpen
    If filedlg.FileName = "" Then Exit Sub
    strFile = filedlg.FileName
    sax.putFeature "schema-validation", True
    sax.putProperty "schemas", m_schemaCache
    Set sax.contentHandler = handler
    Set sax.errorHandler = handler
    sax.parseURL strFile
    Exit Sub
SaxErr:
    MsgBox Err.Description
    Exit Sub
End Sub

The validation is determined by the errors—or lack thereof—that occur during parsing. Once again, DOM code just checks the parseError, whereas SAX2 relies on the handlers being used. The handler for the Schema Tree application is a Visual Basic class defined in Listing 18.15. This class, SAXTest, resembles the handler shown in Listing 18.4. With both content and error handling combined in the SAXTest class, the SAXTest class receives all the notifications needed to validate with SAX. Just as in Listing 18.4, the handler has a number of empty methods that exist only to make sure you fully implement the interfaces you support.

LISTING 18.15 SAXTest.cls (SAX Validation Handler)

'SAXTest
'SAX Handler for XML Schema Validation

Implements IVBSAXContentHandler
Implements IVBSAXErrorHandler

Private Sub IVBSAXContentHandler_characters(strChars As String)

End Sub

Private Property Set IVBSAXContentHandler_documentLocator(_
 ByVal RHS As MSXML2.IVBSAXLocator)

End Property

' Document is validated against the XML Schema
Private Sub IVBSAXContentHandler_endDocument()
    MsgBox "The document is valid according to the schema.", _
     vbOKOnly, "Schema Tree"
End Sub

Private Sub IVBSAXContentHandler_endElement(_
 strNamespaceURI As String, strLocalName As String, 
 strQName As String)

End Sub

Private Sub IVBSAXContentHandler_endPrefixMapping(_
 strPrefix As String)

End Sub

Private Sub IVBSAXContentHandler_ignorableWhitespace(_
 strChars As String)

End Sub

Private Sub IVBSAXContentHandler_processingInstruction(_
 strTarget As String, strData As String)

End Sub

Private Sub IVBSAXContentHandler_skippedEntity(_
 strName As String)

End Sub

Private Sub IVBSAXContentHandler_startDocument()

End Sub

Private Sub IVBSAXContentHandler_startElement(_
 strNamespaceURI As String, strLocalName As String, _
 strQName As String, _
 ByVal oAttributes As MSXML2.IVBSAXAttributes)

End Sub

Private Sub IVBSAXContentHandler_startPrefixMapping(_
 strPrefix As String, strURI As String)

End Sub

' Validation failed for the reason indicated by parameters
Private Sub IVBSAXErrorHandler_error(_
 ByVal oLocator As MSXML2.IVBSAXLocator, _
 strErrorMessage As String, ByVal nErrorCode As Long)
    MsgBox strErrorMessage, vbCritical, "Schema Tree"
End Sub

Private Sub IVBSAXErrorHandler_fatalError(_
 ByVal oLocator As MSXML2.IVBSAXLocator, _
 strErrorMessage As String, ByVal nErrorCode As Long)
    MsgBox strErrorMessage, vbCritical, "Schema Tree"
End Sub

Private Sub IVBSAXErrorHandler_ignorableWarning(_
 ByVal oLocator As MSXML2.IVBSAXLocator, _
 strErrorMessage As String, ByVal nErrorCode As Long)

End Sub 

With this code, we have a minimal XML schema explorer and document validator. Figures 18.5 and 18.6 show the XML Schema Tree loading an XML schema. Items in the tree are given different locations and icons depending on their types. This user interface provides a view of the schema hierarchy.

Figure 18.5 FIGURE 18.5 XML Schema Tree in action.


Figure 18.6 FIGURE 18.6 Validation error for badaddress.xml.


When you load the XML document badaddress.xml, the validation code fails because of the missing customerID attribute in that document. Figure 18.6 shows the message box displayed by the XML Schema Tree application when badaddress.xsd fails to validate against the address schema. This error is caught using the same error-checking code shown in Listing 18.15.

  • + Share This
  • 🔖 Save To Your Account

Discussions

comments powered by Disqus