正如 Mimo 所指出的,将 customertype(或另一个其他元素)定义为包含 XSD 名称空间中的元素是没有问题的,这似乎就是您要问的问题。
但是,如果您的目标是能够验证客户元素(或职业元素,这是您示例中的架构所声明的),那么很难想象一个验证架构是最好的方式(甚至是可行的方式)去关于它。一个原因是,根据正在验证的实例提供的模式信息验证文档实例不会产生与根据已知模式验证数据相同的信心。(将自己置于一个试图破坏您的验证并说服您的系统接受虚假数据为有效的对手的立场。如果对手指定什么是有效的文档实例,那么知道该文档是有效的有多大用处?)
是什么阻止您编写模式并以通常的方式使用它?
[添加,2012 年 10 月 15 日,在 OP 评论之后]
如果我正确理解了您今天早些时候的评论,您的要求是允许除您以外的人指定 customer
他们喜欢的元素类型,但条件是该类型必须包含一个名为 Source 的子元素,其类型将是xsd:int
。您没有指定是否需要访问他们正在使用的类型定义,因此我将尝试考虑您确实需要它的情况和您不需要它的情况。
下面描述了使这种情况起作用的三种方法。他们的共同点是
- 定义模式基本版本的“主”模式文档,以及
- 用于不同情况的一个或多个“辅助”模式文档。
一般来说,您可能会发现找到一本关于 XSD 的好教科书并查看它关于从多个模式文档中的声明创建模式的内容会很有帮助。
(1) 一种方法使用xsi:type
. 您定义一个主模式文档,其中customer
元素具有命名类型;我假设类型是命名的Customer
。该Customer
类型接受其第一个子元素名为 的任何元素Source
。例如:
<xs:element name="customer" type="Customer"/>
<xs:complexType name="Customer">
<xs:sequence>
<xs:element name="Source" type="xs:int"/>
<xs:any minOccurs="0"
maxOccurs="unbounded"
processContents="lax"/>
</xs:sequence>
<xs:anyAttribute processContents="lax"/>
</xs:complexType>
那些想要customer
元素更具体类型的人(我称他们为“用户”)为您的目标命名空间提供辅助模式文档,他们在其中声明了其他复杂的类型限制Customer
。例如,他们可能希望customer
元素包含名为姓名、地址和电话号码的元素:
<xs:complexType name="Customer-for-us">
<xs:complexContent>
<xs:restriction base="Customer">
<xs:sequence>
<xs:element name="Source" type="xs:int"/>
<xs:element ref="name"/>
<xs:element ref="address"/>
<xs:element ref="phone"/>
</xs:sequence>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
这是 Customer 类型的法律限制,因此customer
元素可以使用它。因此,文档实例可能包含如下元素:
<customer xsi:type="Customer-for-us">
<Source>83760273</Source>
<name>Willy Wonka</name>
<address> ... </address>
<phone> ... </phone>
</customer>
该文档根据从其辅助模式文档以及主模式文档构造的模式进行验证,因此以Customer-for-us
通常的方式强制执行类型的定义。
通过使用通配符和宽松的验证,客户类型确保用户可以在他们的类型版本中做任何他们喜欢的事情,只要第一个孩子被命名为 Source 并且具有 int 类型。
(2) 第二种方法在主模式文档中使用了一个漏洞。
您像以前一样编写主模式文档,包括将customer
元素声明为具有 type Customer
。但是主模式文档不包含该类型的声明。相反,您在辅助模式文档中声明 Customer 类型,该类型在验证时以通常的方式与主要模式文档结合(我建议您使用第三个模式文档作为驱动程序并包含其他两个,但是有很多方法可以让它工作)。
同时,需要更具体的 Customer 类型的用户为 Customer 类型编写自己的声明,受制于名为 Source 的第一个子类型的兼容性约束,依此类推。用户使用他们自己的驱动程序文件,该文件将主模式文档和他们的辅助模式文档版本与他们自己的客户类型声明一起嵌入。
这样,xsi:type
就不需要使用该属性。
(3) 第三种方法使用xs:redefine
或(在 XSD 1.1 中)xs:override
工具。
您按照解决方案 (1) 中的描述编写主模式文档。用户根据需要使用xs:redefine
或xs:override
重新定义客户。这个答案已经很长了,所以我不建议包含有关使用重新定义或覆盖的教程。