从组中重写minOccurs

时间:2013-12-17 21:51:26

标签: xml xsd restrictions

我遇到的情况是我没有“拥有”基类型,它允许所有子元素都是可选的。从一般商业角度来看,这是有道理的。例如,说它是:

<xs:complexType name="BaseType">
    <xs:sequence>
        <xs:element name="id" type="xs:string" minOccurs="0"/>
        <xs:element name="name" type="xs:string" minOccurs="0"/>
    </xs:sequence>
</xs:complexType>

此类型的实例将包含在我的进程使用的包含类型中。

<xs:complexType name="MyType">
    <xs:sequence>
        <xs:element name="Widget" type="BaseType"/>
        ...other stuff...
    <xs:sequence>
</xs:complexType>

但是,出于我的特殊目的,我需要始终存在BaseType上的'id'元素。当然,我可以在使用它的代码中强制执行此操作,但有没有办法在xsd中表示这一点?

EDIT 我忘了对方。还有另一种类似的情况,我使用的元素是组而不是基类型。

<xs:group name="Address-Group">
    <xs:sequence>
        <xs:element name="street" type="xs:string" minOccurs="0"/>
        <xs:element name="city" type="xs:string" minOccurs="0"/>
        ...etc....
    </xs:sequence>
</xs:group>

如果我在MyType中使用其中一个,我会有同样的问题试图覆盖像'city'这样的东西的minOccurs。

1 个答案:

答案 0 :(得分:3)

假设for my particular purposes, I need the 'id' element on a BaseType to be present always你的意思总是如此,那么你可以申请重新定义,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<!--XML Schema generated by QTAssistant/XSR Module (http://www.paschidev.com)-->
<xsd:schema xmlns="http://tempuri.org/XMLSchema.xsd" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://tempuri.org/XMLSchema.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:redefine schemaLocation="xsd-overriding-minoccurs-from-a-group.xsd">
        <xsd:complexType name="BaseType">
            <xsd:complexContent>
                <xsd:restriction base="BaseType">
                    <xsd:sequence>
                        <xsd:element name="id" type="xsd:string"/>
                        <xsd:element name="name" type="xsd:string" minOccurs="0"/>
                    </xsd:sequence>
                </xsd:restriction>
            </xsd:complexContent>
        </xsd:complexType>
        <xsd:group name="Address-Group">
            <xsd:sequence>
                <xsd:element name="street" type="xsd:string"/>
                <xsd:element name="city" type="xsd:string" minOccurs="0"/>
            </xsd:sequence>
        </xsd:group>
    </xsd:redefine>
</xsd:schema>

问题是,重新定义“始终”工作,即在使用BaseType的所有实例中,重新定义的定义将优先。换句话说,在XSD中没有内置机制,你可以在这里选择你的上下文,除非你转移到XSD 1.1,你不需要重新定义但需要某种断言。问题是,我冒昧地说,XSD 1.1的支持程度甚至低于XSD 1.0(跨平台而不是支持两者的特定版本,例如Saxon或Xerces)。

这样的XML是有效的:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
<paschidev.dummy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="BaseType" xmlns="http://tempuri.org/XMLSchema.xsd">
    <id>id1</id>
    <name>name1</name> 
</paschidev.dummy>

虽然这个会失败:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
<paschidev.dummy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="BaseType" xmlns="http://tempuri.org/XMLSchema.xsd">
    <name>name1</name> 
</paschidev.dummy>

出现以下错误消息(基于.NET):

Error occurred while loading [], line 4 position 3
The element 'paschidev.dummy' in namespace 'http://tempuri.org/XMLSchema.xsd' has invalid child element 'name' in namespace 'http://tempuri.org/XMLSchema.xsd'. List of possible elements expected: 'id' in namespace 'http://tempuri.org/XMLSchema.xsd'.

或者这个(基于Java):

Error while loading [], line 4 position 8
cvc-complex-type.2.4.a: Invalid content was found starting with element 'name'. One of '{"http://tempuri.org/XMLSchema.xsd":id}' is expected.

重定义适用于支持XSD的XML处理器。但是,一些XSD代码绑定框架或内置XSD支持的数据库引擎可能会咳嗽这个。