简而言之,问题是“我能否在模式中定义一个可以作为整体进行验证的模式?”
解释:
是否可以为以下XML定义模式。我需要为“客户”定义一个模式。"customertype“子元素本身就是一个模式。在customertype中,我应该有一个名为"Source“的元素,这是必需的。
<customer>
<customername>acustomer</customername>
<customertype>
<xs:schema>
<xs:element name="profession">
<xs:complexType>
<xs:sequence>
<xs:element name="Source" type="xs:int" />
<xs:element name="ProfessionName" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:schema>
</customertype>
</customer>是否可以为该xml定义模式,以满足所有要求?
发布于 2012-10-13 01:10:10
正如Mimo所指出的,将customertype (或其他元素)定义为包含XSD名称空间中的元素是没有问题的,这似乎就是您要问的问题。
但是,如果您的目标是能够验证customer元素(或profession元素,这是示例中的模式所声明的),那么很难想象这样的验证体系结构是最好的方式(甚至是可行的方式)。其中一个原因是,根据被验证的实例提供的模式信息验证文档实例不会产生与根据已知模式验证数据的整洁性相同的信心。(设身处地为对手着想,试图颠覆你的验证,说服你的系统接受伪造的数据是有效的。如果对手指定什么是有效的文档实例,那么知道文档是有效的又有多大用处呢?)
是什么阻止了您编写模式并以通常的方式使用它?
此外,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元素包含名为name、address和phone号码的元素:
<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类型的定义是以通常的方式强制执行的。
通过使用通配符和宽松验证,Customer类型确保用户可以在其类型的版本中执行任何操作,只要第一个子类型名为Source并具有int类型。
(2)第二种方法在主模式文档中使用一个漏洞。
您可以像前面一样编写一个主模式文档,包括将customer元素声明为具有Customer类型。但是主架构文档不包含该类型的声明。相反,您可以在辅助模式文档中声明Customer类型,该文档在验证时以通常的方式与主模式文档相结合(我建议您使用第三个模式文档作为驱动程序,并包括其他两个,但有许多方法可以使其工作)。
同时,想要更具体的Customer类型的用户要为Customer类型编写自己的声明,并遵守关于名为Source的第一个子级的兼容性约束,依此类推。用户使用自己的驱动程序文件,该文件将主模式文档和辅助模式文档的版本与他们自己的Customer类型声明一起嵌入。
这样,就不需要使用xsi:type属性了。
(3)第三种方法使用xs:redefine或(在XSD1.1中) xs:override工具。
您可以按照解决方案(1)中的描述编写主模式文档。用户可以根据自己的意愿使用xs:redefine或xs:override重新定义客户。这个答案已经相当长了,所以我不打算包含一个关于重定义或覆盖用法的教程。
发布于 2012-10-11 07:02:56
可以创建一个导入并使用另一个模式的模式。这将使用包含模式的customertype定义customer元素:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://xml.netbeans.org/schema/Notes"
xmlns:tns="http://xml.netbeans.org/schema/Notes"
elementFormDefault="qualified">
<xsd:import namespace="http://www.w3.org/2001/XMLSchema"/>
<xsd:element name="customer">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="customername" type="xsd:string"/>
<xsd:element name="customertype">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="xsd:schema"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>问题是您在customertype模式上有一个额外的条件-所以理论上您应该获得标准的XSD模式并修改它,但是在模式定义中有许多不同的方法来满足这个条件,所以做这个“修改”是非常棘手的(也许是不可能的)
也许更好的方法是限制customertype中可能使用的模式(例如,它必须是具有直接指定的复杂类型的单个元素定义,等等),并编写描述这种受限制的模式定义的XSD模式的子集。
https://stackoverflow.com/questions/12825729
复制相似问题