简体   繁体   中英

How do I generate an xsd enumeration from C# classes?

I have an XSD (XML Schema Definition) file that requires an enumeration list (restriction) composed of all classes in a given ( ScoreService.App_Code.Entities ) namespace.

I'm using xsd.exe automated into the build process to perform the task of creating an XSD file from the classes in question, and it reads them from the runtime assembly correctly ( MyBaseClass , MyClassA , ...), creating the following xsd file with no problems:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="MyBaseClass" nillable="true" type="MyBaseClass" />
  <xs:complexType name="MyBaseClass">
    <xs:sequence>
      <xs:element minOccurs="1" maxOccurs="1" name="Id" type="xs:int" />
    </xs:sequence>
  </xs:complexType>

  <xs:element name="MyClassA" nillable="true" type="MyClassA" />
  <xs:complexType name="MyClassA">
    <xs:complexContent mixed="false">
      <xs:extension base="MyBaseClass" />
    </xs:complexContent>
  </xs:complexType>

  ...

</xs:schema>

But AFAIK, I won't be able to use this in an xsd enumeration. I assume I could do something with class attributes to control the appearance of the XSD output, but most of the attributes I tried are only applicable to properties/members.

I'd wish to produce an XSD structure akin to:

<xs:simpleType name="ParamTypeRestriction">
  <xs:restriction base="xs:string">
    <xs:enumeration value="MyBaseClass"></xs:enumeration>
    <xs:enumeration value="MyClassA"></xs:enumeration>
    ...
  </xs:restriction>
</xs:simpleType>

Is this possible without further automation, like processing the generated xsd file manually? If so, how?

There is no product/library that I am aware of that may do what you need. However, it should be relatively easy in terms of code to put something together which would give you exactly what you need.

This is what I would do, in a way that would limit the number of assumptions I would have to put in place regarding file structure, visibility of classes, etc.

Firstly, I would compile a list of assemblies which contain the classes you wish to capture.

For each assembly in that list, I would get the list of types I need. There are many ways to reflect an assembly; assuming that the assemblies are in the right context (ie all dependencies discoverable), then something like this would do the trick rather easy:

Assembly assembly = Assembly.Load(new AssemblyName() { CodeBase = path })

Get the list of types as you need :

Type[] types = assembly.GetExportedTypes();

For each type, the name of the class would be in type.Name - since you're not interested in the full name.

Use the combined list of types to construct a simple schema, with just one simple type; use classes from System.Xml.Schema . The code would roughly be like this:

    void foo(IEnumerable<Type> types)
    {
        var rs = new XmlSchemaSimpleTypeRestriction
        {
            BaseTypeName = new XmlQualifiedName("string", XmlSchema.Namespace)
        };
        foreach (var t in types)
        {
            rs.Facets.Add(new XmlSchemaEnumerationFacet {Value = t.Name});
        }
        var schema = new XmlSchema();
        schema.Items.Add(new XmlSchemaSimpleType
        {
            Name = "ParamTypeRestriction",
            Content = rs
        });
        schema.Write(...);
    }

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM