I have an XML Schema file (XSD) which I'm using to generate C# classes using the xsd tool supplied with Visual Studio.
If it's possible, how do I specify an existing type as the type of an element? Say I want to do this
<xs:element name="Table">
<xs:complexType>
<xs:all>
<!-- ...snip... -->
<xs:element name="CellValues" type="ADODB.RecordSet"/>
</xs:all>
</xs:complexType>
</xs:element>
How do I tell xsd that ADODB.RecordSet
is an existing type in an imported assembly?
Perhaps this would help?
(from http://msdn.microsoft.com/en-us/library/x6c1kb0s(v=vs.71).aspx )
/t[ype]:typename
Specifies the name of the type to create a schema for. You can specify multiple type arguments. If typename does not specify a namespace, Xsd.exe matches all types in the assembly with the specified type. If typename specifies a namespace, only that type is matched. If typename ends with an asterisk character (*), the tool matches all types that start with the string preceding the *. If you omit the /type option, Xsd.exe generates schemas for all types in the assembly.
I'm not sure if this is the best way, but I managed to do something by implementing SchemaImporterExtension
:
namespace SchemaImport
{
public class ADODBSchemaImporterExtension : SchemaImporterExtension
{
public override CodeExpression ImportDefaultValue(string value, string type)
{
return new CodeTypeReferenceExpression(type);
}
public override string ImportSchemaType(XmlSchemaType type,
XmlSchemaObject context, XmlSchemas schemas, XmlSchemaImporter importer,
CodeCompileUnit compileUnit, CodeNamespace codeNamespace,
CodeGenerationOptions options, CodeDomProvider codeGenerator)
{
return null;
}
public override string ImportSchemaType(string name,
string ns, XmlSchemaObject context, XmlSchemas schemas, XmlSchemaImporter importer,
CodeCompileUnit compileUnit, CodeNamespace mainNamespace,
CodeGenerationOptions options, CodeDomProvider codeProvider)
{
if (name.StartsWith("ADODB."))
{
compileUnit.ReferencedAssemblies.Add("adodb.dll");
mainNamespace.Imports.Add(new CodeNamespaceImport("ADODB"));
return name.Substring(name.IndexOf(".") + 1);
}
return null;
}
}
}
together with defining the ADODB.Recordset
as an xsd:complexType
:
<xs:element name="Table">
<xs:complexType>
<xs:all>
<!-- ...snip... -->
<xs:element name="CellValues" type="ADODB.RecordSet"/>
</xs:all>
</xs:complexType>
</xs:element>
<xs:complexType name="ADODB.Recordset"/>
I then had to add this class to machine.config
:
<system.xml.serialization>
<schemaImporterExtensions>
<add type="SchemaImport.ADODBSchemaImporterExtension, SchemaImport, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cd583032ee337c41" />
</schemaImporterExtensions>
</system.xml.serialization>
and specify the assembly in a parameter file (the /p:parameters.xml
switch) to xsd.exe:
<?xml version="1.0" encoding="UTF-8"?>
<xsd xmlns='http://microsoft.com/dotnet/tools/xsd/'>
<generateClasses language='c#' namespace='TableDocument'>
<schemaImporterExtensions>
<type>SchemaImport.ADODBSchemaImporterExtension, SchemaImport, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cd583032ee337c41</type>
</schemaImporterExtensions>
</generateClasses>
</xsd>
I ended up with a .cs file with the appropriate Table class, in the TableDocument namespace that had the ADODB as a reference and using
statement.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.