2011-12-12 66 views
4

这是我反对的一个广义示例。xsi上的约束或限制:类型

我已经在我的模式中创建了派生类型,并且想要创建一个无限列表(序列)的元素,该列表有一个限制,其中只允许三个派生类型中的两个。

要从顶级视图说“我有事件发生在一种情况下只能有两种类型的事件”。

这是我如何定义我的事件和序列的后续持有者。 (这一切都有效并且有效)。

抽象的项目是一个复杂类型命名为“活动基地”,并有一个名为名称的属性相同:

<xs:complexType name="EventBase"> 
    <xs:annotation><xs:documentation>***Abstract Event***</xs:documentation></xs:annotation> 
    <xs:attribute name="Name"/> 
</xs:complexType> 

然后,我必须从抽象得出三个事件如下

<xs:complexType name="DerivedEvent1"> 
    <xs:complexContent> 
     <xs:extension base="EventBase"> 
      <xs:attribute name="Alpha" type="xs:string"/> 
     </xs:extension> 
    </xs:complexContent> 
</xs:complexType> 
<xs:complexType name="DerivedEvent2"> 
    <xs:complexContent> 
     <xs:extension base="EventBase"> 
      <xs:attribute name="Beta"/> 
     </xs:extension> 
    </xs:complexContent> 
</xs:complexType> 
<xs:complexType name="DerivedEvent3"> 
    <xs:complexContent> 
     <xs:extension base="EventBase"> 
      <xs:attribute name="Gamma"/> 
     </xs:extension> 
    </xs:complexContent> 
</xs:complexType> 

要设计一个复杂的对象来保存衍生事件,我创建了一个从抽象复合体派生的具体“通用”事件

<xs:element name="Event" type="EventBase"> 
    <xs:annotation><xs:documentation>A generic event derived from abstract.</xs:documentation></xs:annotation> 
</xs:element> 

然后我希望能够保存事件,所以我创建了一个新的复杂对象来保存上面显示的“通用”事件,但实际上将持有最终消费者派生的事件。

<xs:complexType name="EventsCollectionType"> 
    <xs:annotation><xs:documentation>Holds derived events</xs:documentation></xs:annotation> 
    <xs:sequence> 
     <xs:element ref="Event" maxOccurs="unbounded"/> 
    </xs:sequence> 
</xs:complexType> 

最后,我创建了集合类型派生的元素将举行实际事件:

<xs:element name="Events"><xs:annotation><xs:documentation>Concrete holder of events.</xs:documentation></xs:annotation> 
    <xs:complexType> 
     <xs:sequence> 
      <xs:element ref="Event" maxOccurs="unbounded"/> 
     </xs:sequence> 
    </xs:complexType> 
</xs:element> 

生成的XML看起来是这样的:

<?xml version="1.0" encoding="UTF-8"?> 
<Events xsi:noNamespaceSchemaLocation="file:///C:/StackOverflow.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <Event xsi:type="DerivedEvent1" Name="D1" Alpha="Content1"/> 
    <Event xsi:type="DerivedEvent3" Name="D1" Gamma="Content3"/> 
</Events> 

所以问题是,我怎样才能创建一个最终的事件* s *我只持有特定的xsi:输入的项目?

因此,在限制认为只有派生类型1和3有效的情况下(如上);但是如果它有一个派生类型2,它将是无效的。

我创建了一个公共GIST(Constraint or Restriction on xsi:type

回答

1

我可能是错的,但我不认为这是可能的。

在Events集合中,您基本上希望拥有不同的结构,但都具有相同的元素名称“Event”。这违背了模式的基本约束:http://www.w3.org/TR/xmlschema-1/#cos-element-consistent。使用xsi:type为模式处理器提供了一个提示,它可以消除这种结构的选择,从而避免违反此规则。它基本上是一个解决方法。

难道你不能调用每一个不同的东西,所以你有一个“事件1”和“事件3”的集合或包含一系列可选的“事件1”和“事件3”的外部集合?以这种方式架构执行结构会容易得多。此外,你根本不需要使用xsi:type。我不确定在实例中是否使用了xsi:type来尝试解决此限制或其他原因,但对于使用该模式的任何人来说,不必担心派生类型。

或者,您可以使用其他技术(例如schematron)来帮助实施此限制。

+0

我同意 - 我认为你对派生的使用只会增加复杂性,而我看不到真正的收益。分别为每个事件类型制作序列。 – gilligan