【发布时间】:2016-11-28 09:14:17
【问题描述】:
我正在使用 CodeDOM 从多个 xsd 文件构建代码。所以让我们假设我们有一些从 xsd 中定义的命名空间到已经创建的程序集中的映射:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:abw="MyNamespace" xmlns:bfm="BaseNamespace"
xmlns:gml="http://www.opengis.net/gml/3.2" elementFormDefault="qualified" targetNamespace="MyNamespace"
version="1.0.1.0">
<import namespace="BaseNamespace" schemaLocation="Base.xsd"/>
<import namespace="http://www.opengis.net/gml/3.2" schemaLocation="http://schemas.opengis.net/gml/3.2.1/gml.xsd"/>
<element name="MyClass" substitutionGroup="bfm:MyBaseClass" type="abw:MyClassType"/>
<complexType name="MyClassType">
<complexContent>
<extension base="bfm:MyBaseClassType">
<sequence>
<element maxOccurs="unbounded" minOccurs="0" name="Property1" type="gml:ReferenceType">
<annotation>
<appinfo>
<targetElement xmlns="http://www.opengis.net/gml/3.2">abw:MyClass2</targetElement>
<reversePropertyName xmlns="http://www.opengis.net/gml/3.2">abw:MyClassAlias</reversePropertyName>
</appinfo>
</annotation>
</element>
</sequence>
</extension>
</complexContent>
</complexType>
</schema>
现在 - 由于命名空间 BaseNamespace 和 gml 的程序集已经存在 - 我只想构建 MyClass 的源代码,它应该自动引用基类 bfm:MyBaseClass 和 gml:ReferenceType添加using-directive。
所以我为targetNamespace 创建了一个CodeNamespace,它应用来自xsd 的命名空间MyNamespace。现在我循环该CodeNamespace 中的类型并过滤那些存在于我的xsd 中的类型,因为引用的xsd 文件中的所有其他类型已经具有 分配给它们的程序集。如果一个类型没有在我的 xsd 中定义,它应该不添加到代码中,但是应该添加一个using。
var codeNamepscace = new CodeNamespace("targetNamepscae");
var tmp = code.Types.Cast<CodeTypeDeclaration>().ToArray();
foreach (var type in tmp)
{
var typeFromSchema = schema.SchemaTypes.Names.Cast<XmlQualifiedName>().FirstOrDefault(x => x.Name == type.Name);
if (typeFromSchema == null)
{
string xsdNamespace = ???; // how to get the xsd-namespace for the current type here?
Console.WriteLine(String.Format("Found referenced type {0} which is not declared in current schema", type.Name));
// omit the type from the current namespace and add a using-directive to the generated source-file if not yet done
code.Types.Remove(type);
// add a using-directive for the type if not already done
if (!((IList)code.Imports).Contains(typeFromSchema.Namespace)) code.Imports.Add(new CodeNamespaceImport(GetDotNetNSFromXsdNS(xsdNamespace)));
}
}
方法GetDotNetNSFromXsdNS 定义了从xsd 文件中定义的命名空间到程序集中的命名空间的映射。
我现在的问题是:如何从 xsd 中为我的CodeNamepspace 中的类型获取命名空间?特别是:如何从生成中排除 gml:ReferenceType 和 bfm:MyBaseClass 并通过 using 添加它们?
【问题讨论】:
标签: c# .net xsd code-generation