【发布时间】:2012-09-09 19:42:06
【问题描述】:
这将是一个很长的帖子,谢谢你的准备:-) 这个问题来自这篇文章的一个更高层次的“观点”:
Storing meta information to class properties
我们有一个 XSD,我们将从 (C#/Java) 生成类。所以问题分为两个不同的部分:在 XSD 中定义它,然后从中创建数据模型。
我们希望在复杂类型中包含一些元素来携带元信息,但只是在 XSD 中的某些 x 路径中。这意味着当一个类型被重用为另一个复杂类型中的元素时,我们想告诉用户它是否与某些东西“相关”(我在另一篇文章中称其为安全相关)。相关性在几个层次上表示。 (这种解释当然也适用于 C#/Java 中的数据模型)
XSD 类型示例:
<xs:complexType name="Core">
<xs:sequence>
<xs:element name="No" type="xs:int" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="ComplexA">
<xs:sequence>
<xs:element name="Info" type="Core" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="ComplexB">
<xs:sequence>
<xs:element name="Info" type="Core" />
</xs:sequence>
</xs:complexType>
Core 类型有一个属性“No”。此属性可能与其他类型相关。例如,它应该是 ComplexA.Info 类型中的“relevant-level-1”,而在 ComplexB.Info 中不是。
我们想出了两种不同的方法来实现这一点:
1:在类型级别引入属性:
<xs:complexType name="ComplexA">
<xs:sequence>
<xs:element name="Info" type="Core" />
</xs:sequence>
<xs:attribute name="Relevance.Info.No" type="RelevanceType" fixed="Relevance1"/>
</xs:complexType>
<xs:simpleType name="RelevanceType">
<xs:restriction base="xs:string">
<xs:enumeration value="Relevance1" />
<!-- Some more relevance values -->
</xs:restriction>
</xs:simpleType>
属性“Relevance.Info.No”基本上告诉成员“Info”中的属性“No”具有关联类型“Relevance1”。这种方法显然有一些缺点。类生成非常复杂,因为我们必须手动处理这些属性信息。解决方案在开头提到的线程中发布。
2:为每个具有相关级别的属性引入另一种复杂类型:
这将解决这种“元数据”附加到属性的方式,但显然会在 XSD 和 C#/Java 上为类型中的每个相关级别组合生成 很多 类。
您可以想象,在 C# 和 Java 端创建数据模型的问题与 XSD 中的问题非常相似。最好的方法是让 XSD 准备好自动创建 java 类 (JaxB) 和 C# 类 (XGen),而无需对生成的代码进行任何其他操作(我现在正在这样做)。
您认为还有其他实现这一目标的可能性吗?
感谢任何帮助!
【问题讨论】:
-
属性在给定上下文中的相关性是实例的函数,还是纯粹是类系统的函数?从您的示例中使用
fixed值来看,我想它在实例中不会有所不同;如果是这样,我想知道element引用上的扩展属性是否足够? ` -
@C.M.Sperberg-McQueen:相关性可以从模型路径到模型路径有所不同,它只是针对该特定类型层次结构的所有实例固定。关于属性扩展:无论哪种方式,这只会简化语法,对吗?
标签: c# java xsd code-generation metadata