一个很棒的实用工具,用于将 XML 架构转换为类
将 XML 模式转换为类的实用程序。
引言
当我在一个大量使用 XML 的项目中时,我开始编写这个应用程序。 这个应用程序的作用基本上是复制 Microsoft 的 XSD 工具的功能,但增加了一些额外的漂亮功能。
背景
该应用程序的核心功能是利用 XML 的功能和 .NET 框架的 CodeDom 编写的。 有一些选项可能非常有用,例如从 XML 属性自动转换为字段/属性对。 此外,您可以告诉解析器使用通用命名空间来创建子项集合,而不是数组。 如果您想添加一些功能,我建议您对 Sytem.CodeDom
命名空间有一些了解。
使用代码
我只需要代码文件
如果您只想使用一个可以帮助您日常工作的工具,那么应用程序本身非常简单,您不需要太多说明...只需获取一个 XML 模式,提供一个输出路径(默认情况下,它与模式位于同一位置),以及一个文件名。 完成此操作后,您可以选择一些不错的选项,例如目标语言、使用泛型而不是标准数组、默认命名空间等。 使用这些设置,只需点击几下,即可获得全新的类文件! 只需单击编译并保存,就完成了。 注意:所有类都生成为 partial
,以允许可扩展性,而无需担心重新生成类(如果您的模式正在增长)。
今天,我想我会添加一些东西...
相反,如果您想创建自己的 UI,或者想在其他项目中使用解析功能,所有这些都包含在一个名为 codeProcessor
的静态类中。 这个类的用法非常简单。 事实上,如果您想从模式创建一个类文件,您只需调用一个方法
public static CodeNamespace Process(string xsdFile,
string targetNamespace,
bool chooseElement,
string elementName)
所有“密集任务”都位于这个单一方法中。 特别是,该方法分为三个区域,一个用于 XML 模式解析,一个用于 CodeDom 生成,一个用于 CodeDom 编写。
XML 模式解析不应该被修改,它只是在内存中编译模式。 诸如添加注释和默认值之类的“额外功能”在 CodeDom 生成中处理。 如果您想管理其他功能,我建议您使用此部分处理 XML 片段,并使用 CodeDom 编写部分创建实际的代码元素。 例如,属性默认值是这样管理的
var defaultAtts = from XmlSchemaAttribute att in
((XmlSchemaComplexType)element).Attributes.Cast<xmlschemaattribute>()
where att.DefaultValue != null
select att;
if(defaultAtts.Count()>0){
foreach (XmlSchemaAttribute attribute in defaultAtts)
{
member.UserData.Add(string.Format("default.{0}", attribute.Name),
attribute.DefaultValue);
}
}
其中 member
是一个内部变量,用于管理从模式编译的 CodeMember
对象。 这样,在 CodeDom 编写操作期间,UserData 集合通过创建正确的代码片段进行解析。
CodeDom 编写负责以 CodeDom 对象的形式创建代码片段。 如果您从未接触过 .NET 框架的这一部分,我建议您阅读一些关于此主题的优秀文章,并尝试深入了解。 在本节中,处理所有与“额外功能”相关的操作,例如从数组更改为泛型、包括命名空间、默认值等等。 它还添加了一个默认构造函数(没有参数)来执行初始化任务。 例如
foreach(CodeTypeDeclaration defaultV in defaultValueTypes){
foreach(System.Collections.DictionaryEntry kvp in defaultV.UserData){
ctor.Statements.Add(new CodeAssignStatement(
new CodeVariableReferenceExpression(kvp.Key.ToString().Substring(8)),
new CodeSnippetExpression(kvp.Value.ToString())));
}
}
在上面的代码片段中,报告了代码生成的默认值的管理。 通过检查所有具有默认值的类型,将语句添加到默认构造函数中以初始化每个字段的值。 如果您是 CodeDom 命名空间的新手,理解代码片段可能会有点棘手。 这是它的工作原理的解释:ctor
变量,类型为 CodeTypeConstructor
,有一个语句集合,所有默认赋值都添加到其中。 这是通过创建 CodeAssignStatement
实现的,其中必须指定一个左表达式和一个右表达式。 左表达式是对字段名称的引用,右表达式是一个片段(允许您在 CodeDom 对象中放置普通文本,并在 XML 模式中指定默认值)。 上面片段的结果应该如下所示
这是 XML 模式片段
...
<xs:complexType name="ControlProperties" abstract="true">
<xs:attribute name="Enabled" type="xs:boolean"
use="optional" default="true">
...
这是生成的代码片段
[System.Xml.Serialization.XmlIncludeAttribute(typeof(GridViewProperties))]
[System.CodeDom.Compiler.GeneratedCodeAttribute("XMLtoClass", "1.0.0.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://schemaName.xsd")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://schemaName.xsd",
IsNullable=true)]
public abstract partial class ControlProperties {
private bool enabledField;
public ControlProperties() {
this.enabledField = true;
}
关注点
我认为最大的 POI 是该应用程序提供的“额外”功能,允许放置注释块和默认值,这些都是标准 XSD 工具无法实现的!
下一步
我想在以后版本中添加的是一个选项,可以选择一个单一的整体文件或将所有类拆分成单个文件,也许存储在文件夹结构中。 这可以帮助改进一些真的令人烦恼的后期创建工作。
当然,如果有人想贡献,我们随时欢迎您!