【问题标题】:How do I generate an xsd enumeration from C# classes?如何从 C# 类生成 xsd 枚举?
【发布时间】:2015-12-03 23:15:57
【问题描述】:

我有一个 XSD(XML 架构定义)文件,它需要一个由给定 (ScoreService.App_Code.Entities) 命名空间中的所有类组成的枚举列表(限制)。

我在构建过程中自动使用xsd.exe 来执行从相关类创建 XSD 文件的任务,并从运行时程序集中正确读取它们(MyBaseClassMyClassA、.. .),创建以下 xsd 文件没有问题:

<?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>

但是 AFAIK,我无法在 xsd 枚举中使用它。我假设我可以使用类属性来控制 XSD 输出的外观,但我尝试的大多数属性仅适用于属性/成员。

我希望生成类似于以下内容的 XSD 结构:

<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>

如果没有进一步的自动化,这是否可能,例如手动处理生成的 xsd 文件?如果有,怎么做?

【问题讨论】:

  • 您知道枚举的成员是字符串,而不是类名吗?当然你可以在代码中创建一个enum ParamTypeRestriction { MyBaseClass, MyClassA, ... },这会产生你想要的xsd,但这可能不是你想要做的,因为枚举值与类无关,只是它们碰巧有相同的名称.
  • @Martin 我真正需要的是给定命名空间中所有类(每个类都是字符串)的 names 编译成 XSD 中的枚举。基本上这样我就可以为 XML 文件自动更新这些类的列表。
  • 好吧,如果每个文件有一个类,并且文件以该类命名,则基本上可以使用dir 来创建具有此类枚举的文件,但这会有点骇人听闻的......
  • 命名空间层次结构无论如何都反映了目录设置,所以这实际上是一个相当不错的想法,而且在代码一致性方面一点也不骇人听闻。毕竟只需要类名。

标签: c# visual-studio xsd xsd.exe


【解决方案1】:

据我所知,没有任何产品/库可以满足您的需求。然而,就代码而言,将一些东西放在一起应该会相对容易,这会给你提供你所需要的东西。

这就是我要做的,以一种限制我必须就文件结构、类的可见性等进行的假设数量的方式。

首先,我将编译一个程序集列表,其中包含您希望捕获的类。

对于该列表中的每个程序集,我会得到我需要的类型列表。有很多方法可以反映一个程序集;假设程序集在正确的上下文中(即所有依赖项都可发现),那么这样的事情会很容易做到:

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

获取as you need的类型列表:

Type[] types = assembly.GetExportedTypes();

对于每种类型,类的名称将在 type.Name 中 - 因为您对全名不感兴趣。

使用类型的组合列表构造一个简单的模式,只有一个简单类型;使用来自System.Xml.Schema 的类。代码大概是这样的:

    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(...);
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-21
    • 2021-07-11
    • 2011-01-16
    • 1970-01-01
    相关资源
    最近更新 更多