gpt4 book ai didi

c# - 在C#中从XML Schema生成代码的限制是什么?

转载 作者:IT王子 更新时间:2023-10-29 04:48:27 31 4
gpt4 key购买 nike

我已经看到了几个有关使用xsd.exe从XML Schema生成类的问题的问题,以及有关如何预处理该模式(通常使用XSLT)以在生成之前解决一些棘手方面的建议。我的问题是,是否有可能构建与XML Schema 100%兼容的C#代码生成器。 xsd.exe的问题仅仅是它的实现问题,还是指向XML Schema和C#之间的根本矛盾?

特别是,我对如何将XML Schema中的概念映射到C#感兴趣-接受的映射是什么,哪些映射值得商,,是否存在本质上不可映射的XML Schema构造,以及是否有未被充分利用的C#构造? ?是否有一个合规性规范可以提供映射规则,以便可以实现和测试?

编辑:为了清楚起见,我充分意识到XML Schema不会为我提供完全实现的C#接口(interface),我对它是否可以完全映射到C#类层次结构感兴趣。

编辑2:我添加了一个小赏金,因为我想获得更多细节。

编辑3:赏金计划仍然开放,但到目前为止,它已迈向stakx-一个很好的答案,但主要涉及如何在XML Schema中复制C#结构,而不是相反。好的输入。

最佳答案

有趣的问题。不久之前,我想知道完全相同的事情。
我将举几个例子说明我走了多远。我的演示尚不完整(考虑到XML Schema规范相当全面),但足以显示...

  • 可以说xsd.exe 更好(如果您在编写XML Schema时愿意遵循某些模式);和
  • ,即 XML Schema允许使用C#无法表达的类型声明。考虑到XML和C#是用途完全不同的非常不同的语言,这不足为奇。

  • 在XML模式中声明接口(interface)
    可以在XML模式中使用复杂类型定义C#接口(interface)。例如:
    <xsd:complexType name="IFoo" abstract="true">
    <xsd:attribute name="Bar" type="xsd:string" use="required" />
    <xsd:attribute name="Baz" type="xsd:int" use="optional" />
    </xsd:complexType>
    相当好地对应于:
    interface IFoo
    {
    string Bar { get; set; }
    int? Baz { get; set; }
    }
    这里的模式是抽象的和命名的(非匿名)复杂类型基本上是C#中接口(interface)的XML Schema等效项。
    注意映射的一些问题:
  • C#访问修饰符(例如publicinternal等)无法在XML模式中呈现。
  • 您无法表达XML模式中C#字段与属性之间的差异。
  • 您不能在XML模式中定义方法。
  • 您也无法表达C#structclass之间的差异。 (XML Schema中仅存在类型,这些类型大致对应于.NET值类型;但是与复杂类型相比,它们在XML Schema中受到的限制要大得多。)
  • usage="optional"的用法可用于映射可为空的类型。在XML模式中,您可以将字符串属性定义为可选。过渡到C#时,翻译会发生一些损失:由于string是引用类型,因此无法将其声明为可为空(因为默认情况下它已为可为空)。
  • XML Schema还允许使用usage="prohibited"。这又是不能用C#或至少不能以一种很好的方式(AFAIK)表示的东西。
  • 从我的实验看来,xsd.exe永远不会从抽象的复杂类型生成C#接口(interface)。它将与abstract class一起保留。 (我猜测这是为了使翻译逻辑相当简单。)

  • 声明抽象类
    抽象类可以与接口(interface)非常相似地完成:
    <xsd:element name="FooBase" abstract="true">
    <xsd:complexType>
    ...
    </xsd:complexType>
    </xsd:element>
    在这里,您定义了一个 abstract属性设置为 true的元素,并在其中嵌入了匿名复杂类型。
    这对应于C#中的以下类型声明:
    abstract class FooBase { ... }
    宣告类(class)
    如上所述,但是省略 abstract="true"
    声明实现接口(interface)的类
    <xsd:complexType name="IFoo" abstract="true">
    ...
    </xsd:complexType>

    <xsd:element name="Foo" type="IFoo" />
    这映射到:
    interface IFoo { ... }

    class Foo : IFoo { ... }
    也就是说,您既定义了命名的抽象复杂类型(接口(interface)),又定义了具有该类型的命名元素。
  • 请注意,上面的C#代码段包含两次...,而XML Schema代码段仅包含一个...。怎么会?
    因为您不能定义方法(代码),也不能指定访问修饰符,所以不需要用XML Schema中的元素“实现”复杂类型。复杂类型的“实现”将与原始声明相同。如果复杂类型定义了一些属性,则只需将它们映射到C#接口(interface)实现中的自动属性。

  • 在XML模式中表达继承关系
    可以通过类型扩展和元素替换组的组合来定义XML Schema中的类和接口(interface)继承:
    <xsd:element name="Base" type="base" />
    <xsd:element name="Derived" substitutionGroup="Base" type="derived" />
    <!-- ^^^^^^^^^^^^^^^^^^^^^^^^ -->

    <xsd:complexType name="base">
    <xsd:attribute name="Foo" type="xsd:boolean" use="required" />
    </xsd:complexType>

    <xsd:complexType name="derived">
    <xsd:complexContent>
    <xsd:extension base="base"> <!-- !!! -->
    <xsd:attribute name="Bar" type="xsd:string" use="required" />
    </xsd:extension>
    </xsd:complexContent>
    </xsd:complexType>
    这映射到:
    class Base
    {
    bool Foo { get; set; }
    }

    class Derived : Base
    {
    string Bar { get; set; }
    }
    笔记:
  • 我们再次使用命名的复杂类型。但是这次,他们没有定义abstract="true",因为我们没有定义任何C#接口(interface)类型。
  • 注意引用:元素DerivedBase的替换组中;同时,复杂类型derived是复杂类型base的扩展。 Derived的类型为derivedBase的类型为base
  • 不是抽象的命名复杂类型在C#中没有直接对应的类型。它们不是类,因为它们不能被实例化(在XML中,元素而不是类型,其功能与F#中的值构造函数或C#中的对象实例化大致相同);它们也不是真正的接口(interface),因为它们没有被声明为抽象的。

  • 我的答案未涵盖的某些内容
  • 显示如何在XML Schema中声明实现多个接口(interface)的C#类类型。
  • 显示XML Schema中复杂的内容如何映射到C#(我首先猜想C#中根本没有对应关系;至少在一般情况下没有)。
  • enum。 (它们通过enumeration,btw限制一个简单的类型在XML Schema中实现。)
  • 类中的
  • const字段(这些字段可能映射到具有fixed值的属性)。
  • 如何将xsd:choicexsd:sequence映射到C#;如何正确将IEnumerable<T>ICollection<T>IList<T>IDictionary<TKey, TValue>映射到XML模式?
  • XML Schema简单类型,听起来像是.NET值类型的相应概念;但受到更多限制,并具有不同的目的。

  • 我还没有显示更多的东西,但是到目前为止,您可能已经可以看到示例背后的基本模式。
    为了正确地完成所有这些工作,必须系统地浏览XML Schema规范,并查看那里提到的每个概念如何最好地映射到C#。 (也许没有唯一的最佳解决方案,但是有几种选择。)但是我明确地打算仅显示几个有趣的示例。我希望这仍然足够有用!

    关于c# - 在C#中从XML Schema生成代码的限制是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4842818/

    31 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com