tags:

views:

411

answers:

1

I'm trying to create a treeview in a VB 2008 project that shows all the elements and attributes of an XML Schema.

The MSDN documentation for XML schemas seems to imply that by loading the schema into an XMLSchemaSet and compiling it I should get access to all the elements and attributes with their values but this doesn't seem to work in practice.

Using a for loop such as:

For Each elem As XmlSchemaElement In compiledSchema.Elements.Values

I can use elem.Name to get the element name (and attribute name with a similar nested loop) for a simple type but this doesn't work for a complex type.

Whenever (and however) I try to get values for complex types I hit a brick wall.

As an example, the schema below only returns the "bookstore" element.

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.contoso.com/books" xmlns:xs="http://www.w3.org/2001/XMLSchema"&gt;
    <xs:element name="bookstore">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="unbounded" name="book">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="title" type="xs:string" />
                            <xs:element name="author">
                                <xs:complexType>
                                    <xs:sequence>
                                        <xs:element minOccurs="0" name="name" type="xs:string" />
                                        <xs:element minOccurs="0" name="first-name" type="xs:string" />
                                        <xs:element minOccurs="0" name="last-name" type="xs:string" />
                                    </xs:sequence>
                                </xs:complexType>
                            </xs:element>
                            <xs:element name="price" type="xs:decimal" />
                        </xs:sequence>
                        <xs:attribute name="genre" type="xs:string" use="required" />
                        <xs:attribute name="publicationdate" type="xs:unsignedShort" use="required" />
                        <xs:attribute name="ISBN" type="xs:string" use="required" />
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

Is there any way of of populating the treeview control so that it shows:

bookstore
  book
    genre
    publication date
    isbn
    title
    author
      first-name
      last-name
    price
A: 

DisplayXmlFile - loading a XML file in a TreeView ' Display a XML file in a TreeView ' Note: requires Imports System.Xml ' Example: DisplayXmlFile("c:\employees.xml", TreeView1)

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Try 'Dim file_name As String = ("c:\employees.xml")

        TreeView1.Nodes.Clear()

        DisplayXmlFile("c:\satellites.xml", TreeView1)
    Catch ex As Exception

    End Try
End Sub

' Display a XML file in a TreeView
' Note: requires Imports System.Xml
' Example: DisplayXmlFile("employees.xml", TreeView1)

Sub DisplayXmlFile(ByVal filename As String, ByVal tvw As TreeView)
    Dim xmldoc As New XmlDocument()
    xmldoc.Load(filename)
    ' Add it to the TreeView Nodes collection
    DisplayXmlNode(xmldoc, tvw.Nodes)
    ' Expand the root node.
    tvw.Nodes(0).Expand()
End Sub

Sub DisplayXmlNode(ByVal xmlnode As XmlNode, ByVal nodes As TreeNodeCollection)
    ' Add a TreeView node for this XmlNode.
    ' (Using the node's Name is OK for most XmlNode types.)
    Dim tvNode As TreeNode = nodes.Add(xmlnode.Name)

    Select Case xmlnode.NodeType
        Case XmlNodeType.Element
            ' This is an element: Check whether there are attributes.
            If xmlnode.Attributes.Count > 0 Then
                ' Create an ATTRIBUTES node.
                Dim attrNode As TreeNode = tvNode.Nodes.Add("(ATTRIBUTES)")
                ' Add all the attributes as children of the new node.
                Dim xmlAttr As XmlAttribute
                For Each xmlAttr In xmlnode.Attributes
                    ' Each node shows name and value.
                    attrNode.Nodes.Add(xmlAttr.Name & " = '" & xmlAttr.Value & _
                        "'")
                Next
            End If
        Case XmlNodeType.Text, XmlNodeType.CDATA
            ' For these node types we display the value
            tvNode.Text = xmlnode.Value
        Case XmlNodeType.Comment
            tvNode.Text = "<!--" & xmlnode.Value & "-->"
        Case XmlNodeType.ProcessingInstruction, XmlNodeType.XmlDeclaration
            tvNode.Text = "<?" & xmlnode.Name & " " & xmlnode.Value & "?>"
        Case Else
            ' ignore other node types.
    End Select

    ' Call this routine recursively for each child node.
    Dim xmlChild As XmlNode = xmlnode.FirstChild
    Do Until xmlChild Is Nothing
        DisplayXmlNode(xmlChild, tvNode.Nodes)
        xmlChild = xmlChild.NextSibling
    Loop
End Sub
joeylemon
This doesn't work for xml schemas. There's no way to return just the element name string.
melkisadek