我正在尝试创建一个可以为通过在.NET中序列化类型生成的XAML生成XSD的工具,但这不是特定于.NET的。
假设我有一个类型。此类型具有属性并且是集合。
public class MyType : Collection<CollectedType>
{
public PType1 PropertyOne {get;set;}
public PType2 PropertyTwo {get;set;}
}
这序列化为以下(省略对象图构造):
<MyType xmlns="clr-namespace:blahblahblah">
<CollectedType name="First instance in the collection"/>
<CollectedType name="Second instance in the collection"/>
<MyType.PropertyOne>
<PType1 Value = "Serialized object in PropertyOne" />
</MyType.PropertyOne>
<MyType.PropertyTwo>
<PType2 Value = "Serialized object in PropertyTwo" />
</MyType. PropertyTwo >
</MyType>
在为此类型生成XSD时,我可以说以下内容:
这一切都相对容易。这是生成的xsd:
的一大块 <xs:complexType name="MyType">
<xs:sequence>
<xs:element name="MyType.PropertyOne" type="PType1"/>
<xs:element name="MyType.PropertyOne" type="PType1"/>
<xs:group ref="CollectedTypeGroup"/>
</xs:sequence>
</xs:complexType>
现在来了困难的部分。因为XML将被映射回对象图,所以我有一个关于如何将元素添加到MyType的限制列表,其中必须强制执行模式。如果未强制执行这三个要求并且仅强制执行这三个要求,我将面临尝试使用我的架构的用户的问题:
1)添加到MyType 的元素不得限于特定订单
2)表示我的对象属性的元素只能出现一次或不出现
3)组元素必须是无界的;它们可以出现在父元素中的任何位置和0 ... *次
这是我有一个可怕的时间。我无法找到令人满意的选择,序列,所有等组合来满足这三个要求。我也尝试将元素放在一个单独的组中,complexTypes等。似乎没什么用。
如何将我的元素和我的组合成一个complexType并满足我的三个要求?
答案 0 :(得分:1)
这是否符合您的需求?
<xs:element name="MyType" type="MyType.Type"/>
<xs:complexType name="MyType.Type">
<xs:sequence>
<xs:group ref="CollectedTypeGroup" minOccurs="0" maxOccurs="unbounded"/>
<xs:choice minOccurs="0">
<xs:sequence>
<xs:element name="MyType.PropertyOne" type="PType1.Type"/>
<xs:group ref="CollectedTypeGroup" minOccurs="0" maxOccurs="unbounded"/>
<xs:sequence minOccurs="0">
<xs:element name="MyType.PropertyTwo" type="PType2.Type"/>
<xs:group ref="CollectedTypeGroup" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:sequence>
<xs:sequence>
<xs:element name="MyType.PropertyTwo" type="PType2.Type"/>
<xs:group ref="CollectedTypeGroup" minOccurs="0" maxOccurs="unbounded"/>
<xs:sequence minOccurs="0">
<xs:element name="MyType.PropertyOne" type="PType1.Type"/>
<xs:group ref="CollectedTypeGroup" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:sequence>
</xs:choice>
</xs:sequence>
</xs:complexType>
<xs:group name="CollectedTypeGroup">
<xs:choice>
<xs:element name="CollectedType" type="CollectedType.Type"/>
<xs:element name="DerivedCollectedType" type="CollectedType.Type"/>
<xs:element name="DerivedCollectedType2" type="CollectedType.Type"/>
</xs:choice>
</xs:group>
<xs:complexType name="CollectedType.Type">
<xs:attribute name="name" type="xs:string"/>
</xs:complexType>
<xs:complexType name="PType1.Type">
<xs:sequence>
<xs:element name="PType1">
<xs:complexType>
<xs:attribute name="Value" type="xs:string"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PType2.Type">
<xs:sequence>
<xs:element name="PType2">
<xs:complexType>
<xs:attribute name="Value" type="xs:string"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
答案 1 :(得分:1)
这让人困惑多年,但是无法在XML Schema中定义这个内容模型。
唯一的模式粒子可以保证元素一次或根本不出现,并且以任何顺序出现xsd:all。但是,正如您可能已经发现的那样,xsd:all中元素的最大界限是1,而不是无界限。
如果您的集合元素有一个容器元素,那么您可以放弃它:
<xs:complexType name="MyType">
<xs:sequence>
<xs:element name="MyType.PropertyOne" type="PType1" minOccurs="0"/>
<xs:element name="MyType.PropertyTwo" type="PType2" minOccurs="0"/>
<xs:element name="collection" type="CollectionType" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="CollectionType">
<xs:sequence>
<xs:group ref="CollectedTypeGroup"/>
</xs:sequence>
</xs:complexType>
将事物分组,复杂类型等等,无法帮助您解决此问题,因为架构处理器会将其展平以执行其验证。
仅供参考,Relax NG没有此限制。您可以使用其“interleave”结构来定义您要查找的内容(它与模式'all'相同,但允许无限制的子项。)
希望这有帮助。