XML Schema(XSD)是用于定义XML文档结构和数据类型的标记语言。它允许开发者定义XML文档的合法性规则,确保数据的一致性和有效性。尽管XML Schema在数据传输和交换中非常重要,但解析和使用XSD的过程往往比较复杂。本文将介绍一种现代且健壮的方法来解析和应用XSD。
XML Schema定义(XSD)是一种用于描述XML文档结构的语言。它允许定义元素、属性、数据类型等的规则。XSD文件通常包含一个或多个元素定义,这些元素定义了XML文档的结构。XSD还支持包括和导入其他XSD文件,以构建复杂的数据模型。
LinqToXsd是一个强大的XSD到LINQ友好代码的生成器。它能够将XSD文件转换为C#代码,使得开发者可以使用LINQ查询来操作XML数据。LinqToXsd的使用非常简单,只需要运行一个命令即可生成对应的C#代码文件。
C:\projects>linqtoxsd.exe xmlschema.xsd
上述命令会生成一个名为xmlschema.cs的C#代码文件,该文件包含了XSD定义的所有元素和类型的C#表示。
解析XSD文件并不是一个简单的加载过程,需要递归地包含后续的XSD文件,并构建它们的对象映射。以下是一个C#方法,用于加载XSD文件并合并所有包含的XSD文件:
public static schema Load(IEnumerable files, IncludedFileResolver resolver)
{
schema mtr = new schema();
foreach (var fil in files)
{
var sch = schema.Load(fil);
Merge(mtr, sch);
var incs = sch.import.Select(q => q.schemaLocation).ToList();
incs.AddRange(sch.include.Select(s => s.schemaLocation));
var resolved = incs.Select(inc => resolver(fil, inc))
.Where(q => null != q);
if (resolved.Count() > 0)
{
Merge(mtr, Load(resolved));
}
}
return mtr;
}
上述代码展示了如何加载XSD文件,并递归地包含和合并所有相关的XSD文件。这个过程确保了所有的XSD定义都被正确地加载和合并。
在遍历XSD定义的过程中,合并对象引用是非常重要的。以下是一个C#方法,用于合并多个XSD定义到一个大型的XSD对象中:
private static void Merge(schema mstr, schema src)
{
mstr.element = MergeList<element>(mstr.element, src.element);
mstr.attribute = MergeList<attribute>(mstr.attribute, src.attribute);
mstr.complexType = MergeList<complexType>(mstr.complexType, src.complexType);
mstr.simpleType = MergeList<simpleType>(mstr.simpleType, src.simpleType);
mstr.include = MergeList<include>(mstr.include, src.include);
mstr.import = MergeList<import>(mstr.import, src.import);
}
上述代码展示了如何合并XSD定义中的元素、属性、复杂类型、简单类型、包含和导入。这个过程确保了所有的XSD定义都被正确地合并到一个统一的对象中。
理解XSD的含义并不简单。本文不打算详细描述XSD的含义,而是推荐一些更好的资源,如W3C的XML Schema标准、XML Schema Wiki和W3C School的XSD入门教程。
已经加载了所有的对象,映射了它们,并找到了它们的有用之处。现在让将它们重新解释为一些不同但仍然有意义的东西。在这种情况下,创建了一种名为"SKA"(来自SKemA)的"新"语言。它只是XSD的一个更自然的C-like重新解释,用于演示。
Type CubInfo {
!Id
!First
!Last
@Place
}
Type GroupInfo {
Cub [0-n]
@Name
}
Type RacersInfo {
Group [0-n]
}
Type ResultInfo {
!CubId
!Time
}
Type RaceInfo {
Result [0-n]
}
Type RacesInfo {
Race [0-n]
}
Type DerbyInfo {
Racers
Races
}
Derby