65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 SOM 解析 XSD Schema

starIconstarIconstarIconstarIconstarIcon

5.00/5 (9投票s)

2008年10月13日

CPOL
viewsIcon

80460

downloadIcon

1358

从 Schema 中提取元数据或生成 XML 映射器

HelloSOM.png

引言

本文展示了如何使用 Schema 对象模型 (SOM) 导航器作为任意 Schema。当您拥有 Schema 并希望生成自己的映射,或者希望构建自定义 XML 生成器或基于 XSD 的代码生成器时,这将非常有用。

Using the Code

首先读取 Schema 并“编译”,这将验证 Schema。

private static XmlSchema
ReadAndCompileSchema(string fileName)
{
    XmlTextReader tr = new XmlTextReader(fileName,
                        new NameTable());

    // The Read method will throw errors encountered
    // on parsing the schema
    XmlSchema schema = XmlSchema.Read(tr,
           new ValidationEventHandler(ValidationCallbackOne));
    tr.Close();

    XmlSchemaSet xset = new XmlSchemaSet();
    xset.Add(schema);

    xset.ValidationEventHandler += new ValidationEventHandler(ValidationCallbackOne);

    // The Compile method will throw errors
    // encountered on compiling the schema
    xset.Compile();

    return schema;
}

private static void ValidationCallbackOne(object sender, ValidationEventArgs args)
{
    Console.WriteLine("Exception Severity: " + args.Severity);
    Console.WriteLine(args.Message);
}

从最高层级开始遍历...

private static void TraverseSOM(string xsfFilename)
{
    XmlSchema custSchema = ReadAndCompileSchema(xsfFilename);

    foreach (XmlSchemaElement elem in
					 custSchema.Elements.Values)
    {
        ProcessElement(elem);
    }
}

只有元素才能包含属性... 因此以略微特殊的方式处理。

private static void ProcessElement(XmlSchemaElement elem)
{
    Console.WriteLine("Element: {0}", elem.Name);

    if (elem.ElementSchemaType is XmlSchemaComplexType)
    {
	XmlSchemaComplexType ct = 
		elem.ElementSchemaType as XmlSchemaComplexType;

	foreach (DictionaryEntry obj in ct.AttributeUses)
		Console.WriteLine("Attribute: {0}  ", 
		(obj.Value as XmlSchemaAttribute).Name);

	ProcessSchemaObject(ct.ContentTypeParticle);
    }
}

泛型地处理 Choice Sequence 元素(这处理了所需的类型转换)。

private static void ProcessSequence(XmlSchemaSequence sequence)
{
    Console.WriteLine("Sequence");
    ProcessItemCollection(sequence.Items);
}

private static void ProcessChoice(XmlSchemaChoice choice)
{
    Console.WriteLine("Choice");
    ProcessItemCollection(choice.Items);
}

Schema 对象以泛型但统一的方式处理。

private static void ProcessItemCollection(XmlSchemaObjectCollection objs)
{
    foreach (XmlSchemaObject obj in objs)
    ProcessSchemaObject(obj);
}

private static void ProcessSchemaObject(XmlSchemaObject obj)
{
    if (obj is XmlSchemaElement)
        ProcessElement(obj as XmlSchemaElement);
    if (obj is XmlSchemaChoice)
        ProcessChoice(obj as XmlSchemaChoice);
    if (obj is XmlSchemaSequence)
        ProcessSequence(obj as XmlSchemaSequence);
}

关注点

有很多类型检查和转换。这是 SOM 使用的数据模型固有的。它不是一个强类型的数据结构。因此您必须检查、转换然后使用。生成一个强类型的 XSD 模型将是一项有趣的练习,但我将其留给另一篇文章。

历史

  • 2008-10-10:创建文章
© . All rights reserved.