Traversing XML Schemas
Traversing an XML schema using the Schema Object Model (SOM) API provides access to the elements, attributes, and types stored in the SOM. Traversing an XML schema loaded into the SOM is also the first step in editing an XML schema using the SOM API.
Traversing an XML Schema
The following properties of the XmlSchema class provide access to the collection of all global items added to the XML schema.
Property |
Object type stored in the collection or array |
---|---|
XmlSchemaExternal, XmlSchemaInclude, XmlSchemaImport, or XmlSchemaRedefine |
|
XmlSchemaObject (provides access to all global level elements, attributes, and types). |
|
XmlAttribute (provides access to attributes that do not belong to the schema namespace) |
Note
All of the properties listed in the table above, except for the Items property, are Post-Schema-Compilation-Infoset (PSCI) properties that are not available until the schema has been compiled. The Items property is a pre-schema-compilation property that can be used before the schema has been compiled to access and edit all global level elements, attributes, and types.
The UnhandledAttributes property provides access to all the attributes that do not belong to the schema namespace. These attributes are not processed by the schema processor.
The code example that follows demonstrates traversing the customer schema created in the Building XML Schemas topic. The code example demonstrates traversing the schema using the collections described above and writes all the elements and attributes in the schema to the console.
The sample traverses the customer schema in the following steps.
Adds the customer schema to a new XmlSchemaSet object and then compiles it. Any schema validation warnings and errors encountered reading or compiling the schema are handled by the ValidationEventHandler delegate.
Retrieves the compiled XmlSchema object from the XmlSchemaSet by iterating over the Schemas property. Because the schema is compiled, Post-Schema-Compilation-Infoset (PSCI) properties are accessible.
Iterates over each XmlSchemaElement in the Values collection of the post-schema-compilation XmlSchema.Elements collection writing the name of each element to the console.
Gets the complex type of the Customer element using the XmlSchemaComplexType class.
If the complex type has any attributes, gets an IDictionaryEnumerator to enumerate over each XmlSchemaAttribute and writes its name to the console.
Gets the sequence particle of the complex type using the XmlSchemaSequence class.
Iterates over each XmlSchemaElement in the XmlSchemaSequence.Items collection writing the name of each child element to the console.
The following is the complete code example.
Imports System
Imports System.Collections
Imports System.Xml
Imports System.Xml.Schema
Class XmlSchemaTraverseExample
Shared Sub Main()
' Add the customer schema to a new XmlSchemaSet and compile it.
' Any schema validation warnings and errors encountered reading or
' compiling the schema are handled by the ValidationEventHandler delegate.
Dim schemaSet As XmlSchemaSet = New XmlSchemaSet()
AddHandler schemaSet.ValidationEventHandler, AddressOf ValidationCallback
schemaSet.Add("http://www.tempuri.org", "customer.xsd")
schemaSet.Compile()
' Retrieve the compiled XmlSchema object from the XmlSchemaSet
' by iterating over the Schemas property.
Dim customerSchema As XmlSchema = Nothing
For Each schema As XmlSchema In schemaSet.Schemas()
customerSchema = schema
Next
' Iterate over each XmlSchemaElement in the Values collection
' of the Elements property.
For Each element As XmlSchemaElement In customerSchema.Elements.Values
Console.WriteLine("Element: {0}", element.Name)
' Get the complex type of the Customer element.
Dim complexType As XmlSchemaComplexType = CType(element.ElementSchemaType, XmlSchemaComplexType)
' If the complex type has any attributes, get an enumerator
' and write each attribute name to the console.
If complexType.AttributeUses.Count > 0 Then
Dim enumerator As IDictionaryEnumerator = _
complexType.AttributeUses.GetEnumerator()
While enumerator.MoveNext()
Dim attribute As XmlSchemaAttribute = _
CType(enumerator.Value, XmlSchemaAttribute)
Console.WriteLine("Attribute: {0}", Attribute.Name)
End While
End If
' Get the sequence particle of the complex type.
Dim sequence As XmlSchemaSequence = CType(complexType.ContentTypeParticle, XmlSchemaSequence)
For Each childElement As XmlSchemaElement In sequence.Items
Console.WriteLine("Element: {0}", childElement.Name)
Next
Next
End Sub
Shared Sub ValidationCallback(ByVal sender As Object, ByVal args As ValidationEventArgs)
If args.Severity = XmlSeverityType.Warning Then
Console.Write("WARNING: ")
Else
If args.Severity = XmlSeverityType.Error Then
Console.Write("ERROR: ")
End If
End If
Console.WriteLine(args.Message)
End Sub
End Class
using System;
using System.Collections;
using System.Xml;
using System.Xml.Schema;
class XmlSchemaTraverseExample
{
static void Main()
{
// Add the customer schema to a new XmlSchemaSet and compile it.
// Any schema validation warnings and errors encountered reading or
// compiling the schema are handled by the ValidationEventHandler delegate.
XmlSchemaSet schemaSet = new XmlSchemaSet();
schemaSet.ValidationEventHandler += new ValidationEventHandler(ValidationCallback);
schemaSet.Add("http://www.tempuri.org", "customer.xsd");
schemaSet.Compile();
// Retrieve the compiled XmlSchema object from the XmlSchemaSet
// by iterating over the Schemas property.
XmlSchema customerSchema = null;
foreach (XmlSchema schema in schemaSet.Schemas())
{
customerSchema = schema;
}
// Iterate over each XmlSchemaElement in the Values collection
// of the Elements property.
foreach (XmlSchemaElement element in customerSchema.Elements.Values)
{
Console.WriteLine("Element: {0}", element.Name);
// Get the complex type of the Customer element.
XmlSchemaComplexType complexType = element.ElementSchemaType as XmlSchemaComplexType;
// If the complex type has any attributes, get an enumerator
// and write each attribute name to the console.
if (complexType.AttributeUses.Count > 0)
{
IDictionaryEnumerator enumerator =
complexType.AttributeUses.GetEnumerator();
while (enumerator.MoveNext())
{
XmlSchemaAttribute attribute =
(XmlSchemaAttribute)enumerator.Value;
Console.WriteLine("Attribute: {0}", attribute.Name);
}
}
// Get the sequence particle of the complex type.
XmlSchemaSequence sequence = complexType.ContentTypeParticle as XmlSchemaSequence;
// Iterate over each XmlSchemaElement in the Items collection.
foreach (XmlSchemaElement childElement in sequence.Items)
{
Console.WriteLine("Element: {0}", childElement.Name);
}
}
}
static void ValidationCallback(object sender, ValidationEventArgs args)
{
if (args.Severity == XmlSeverityType.Warning)
Console.Write("WARNING: ");
else if (args.Severity == XmlSeverityType.Error)
Console.Write("ERROR: ");
Console.WriteLine(args.Message);
}
}
#using <System.Xml.dll>
using namespace System;
using namespace System::Collections;
using namespace System::Xml;
using namespace System::Xml::Schema;
ref class XmlSchemaTraverseExample
{
public:
static void Main()
{
// Add the customer schema to a new XmlSchemaSet and compile it.
// Any schema validation warnings and errors encountered reading or
// compiling the schema are handled by the ValidationEventHandler delegate.
XmlSchemaSet^ schemaSet = gcnew XmlSchemaSet();
schemaSet->ValidationEventHandler += gcnew ValidationEventHandler(ValidationCallback);
schemaSet->Add("http://www.tempuri.org", "customer.xsd");
schemaSet->Compile();
// Retrieve the compiled XmlSchema object from the XmlSchemaSet
// by iterating over the Schemas property.
XmlSchema^ customerSchema = nullptr;
for each (XmlSchema^ schema in schemaSet->Schemas())
{
customerSchema = schema;
}
// Iterate over each XmlSchemaElement in the Values collection
// of the Elements property.
for each (XmlSchemaElement^ element in customerSchema->Elements->Values)
{
Console::WriteLine("Element: {0}", element->Name);
// Get the complex type of the Customer element.
XmlSchemaComplexType^ complexType = dynamic_cast<XmlSchemaComplexType^>(element->ElementSchemaType);
// If the complex type has any attributes, get an enumerator
// and write each attribute name to the console.
if (complexType->AttributeUses->Count > 0)
{
IDictionaryEnumerator^ enumerator =
complexType->AttributeUses->GetEnumerator();
while (enumerator->MoveNext())
{
XmlSchemaAttribute^ attribute =
dynamic_cast<XmlSchemaAttribute^>(enumerator->Value);
Console::WriteLine("Attribute: {0}", attribute->Name);
}
}
// Get the sequence particle of the complex type.
XmlSchemaSequence^ sequence = dynamic_cast<XmlSchemaSequence^>(complexType->ContentTypeParticle);
// Iterate over each XmlSchemaElement in the Items collection.
for each (XmlSchemaElement^ childElement in sequence->Items)
{
Console::WriteLine("Element: {0}", childElement->Name);
}
}
}
static void ValidationCallback(Object^ sender, ValidationEventArgs^ args)
{
if (args->Severity == XmlSeverityType::Warning)
Console::Write("WARNING: ");
else if (args->Severity == XmlSeverityType::Error)
Console::Write("ERROR: ");
Console::WriteLine(args->Message);
}
};
int main()
{
XmlSchemaTraverseExample::Main();
return 0;
};
The XmlSchemaElement.ElementSchemaType property can be XmlSchemaSimpleType, or XmlSchemaComplexType if it is a user-defined simple type or a complex type. It can also be XmlSchemaDatatype if it is one of the built-in datatypes defined in the W3C XML Schema Recommendation. In the customer schema, the ElementSchemaType of the Customer element is XmlSchemaComplexType, and the FirstName and LastName elements are XmlSchemaSimpleType.
The code example in the Building XML Schemas topic used the XmlSchemaComplexType.Attributes collection to add the attribute CustomerId to the Customer element. This is a pre-schema-compilation property. The corresponding Post-Schema-Compilation-Infoset property is the XmlSchemaComplexType.AttributeUses collection, which holds all the attributes of the complex type, including the ones that are inherited through type derivation.
See Also
Concepts
XML Schema Object Model Overview
Reading and Writing XML Schemas
Including or Importing XML Schemas