“某些”元素的XSD属性

时间:2012-09-17 14:50:09

标签: c# java xsd code-generation metadata

这将是一个很长的帖子,谢谢你准备好了:-) 这个问题来自这篇文章的一个级别的“观点”:

Storing meta information to class properties

我们有一个XSD,我们将从中生成类(C#/ Java)。所以问题分为两个不同的部分:在XSD中定义它,然后从中创建数据模型。

我们希望在复杂类型中有一些元素来携带元信息,但只是在XSD中的某些x路径中。这意味着当一个类型被重用为另一个复杂类型中的元素时,我们想告诉用户它是否与某些东西“相关”(我在其他帖子中将其称为安全性)。相关性用几个级别表示。 (该解释也适用于C#/ Java ofcourse中的数据模型)

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中的“related-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上产生很多类。< / p>

您可以想象在C#和Java端创建数据模型的问题与XSD中的问题非常相似。最好的方法是让XSD准备好自动创建java类(JaxB)和C#类(XGen),而不需要对生成的代码进行任何其他操作(我现在正在做)。

您是否看到了实现这一目标的其他可能性?

感谢任何帮助!

2 个答案:

答案 0 :(得分:0)

在这种情况下,我相信你需要使用继承。如果您定义另一个名为CoreBase的类型,并且您在Core

中继承了此类型

您可以在Core中使用ComplexA,然后在CoreBase中使用ComplexB

<xs:complexType name="CoreBase">
  <xs:sequence>
    ... some attributes or how ever you wish
  </xs:sequence>
</xs:complexType>

<complexType name="Core">
    <complexContent>
        <extension base="CoreBase">
            <sequence>
                <xs:element name="No" type="xs:int" />
            </sequence>
        </extension>
    </complexContent>
</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="CoreBase" />
    </xs:sequence>
</xs:complexType>

请参阅xml架构Xsd and inheritance

中的继承链接

答案 1 :(得分:0)

正如我在回答的评论中所述,我认为没有一个干净的解决方案。也许XML不打算像这样使用。
但我仍然对其他解决方案感兴趣...