The following post asks how to indicate that an element is the root element in an XML schema:
Is it possible to define a root element in an XML Document using Schema
Based on the example that you provided, it is possible to find the only root element.
You can get a list of global elements, then get a list a nested elements that referenced in complexType under the node xs:sequence, thus the root element is the one in global elements list but not in nested elements list.
I have done this by using XmlSchemaSet class in .NET. Here is the code snippet:
var localSchema = schemaSet.Schemas().OfType().Where(x => !x.SourceUri.StartsWith("http")).ToList();
var globalComplexTypes = localSchema
.SelectMany(x => x.Elements.Values.OfType())
.Where(x => x.ElementSchemaType is XmlSchemaComplexType)
.ToList();
var nestedTypes = globalComplexTypes.Select(x => x.ElementSchemaType)
.OfType()
.Select(x => x.ContentTypeParticle)
.OfType()
.SelectMany(x => x.GetNestedTypes())
.ToList();
var rootElement= globalComplexTypes.Single(x => !nestedTypes.Select(y => y.ElementSchemaType.QualifiedName).Contains(x.SchemaTypeName));
The extension method GetNestedTypes:
static IEnumerable GetNestedTypes(this XmlSchemaGroupBase xmlSchemaGroupBase)
{
if (xmlSchemaGroupBase != null)
{
foreach (var xmlSchemaObject in xmlSchemaGroupBase.Items)
{
var element = xmlSchemaObject as XmlSchemaElement;
if (element != null)
yield return element;
else
{
var group = xmlSchemaObject as XmlSchemaGroupBase;
if (group != null)
foreach (var item in group.GetNestedTypes())
yield return item;
}
}
}
}
But there still has problems for the general xsd when using this approach. For example, in DotNetConfig.xsd that Visual studio use for configuration file, the root element is define as below:
I havn't found a complete solution to deal with all kinds of schemas yet. Will continue for it.