Inability to suppress attribute from parent in child element (xsd constraint)

I want to suppress the subjectIdentifier attribute (which is declared in the parent ConsumerSubjectResponseType ) in the child of CombinedConsumerSubjectResponseType . I thought that repeating an attribute declaration in a child would be enough, but apparently it is not. Can this be done in xsd?

<xs:complexType name="ConsumerSubjectResponseType"> <xs:sequence> <xs:element name="CustomerReferenceNumber" type="xs:string" minOccurs="0"/> <xs:element name="Sources" type="xs:string" minOccurs="0"/> <xs:element name="AdditionalOutputData" type="xs:string" minOccurs="0"/> </xs:sequence> <xs:attribute name="subjectIdentifier" type="xs:string" use="required"/> </xs:complexType> <xs:complexType name="CombinedConsumerSubjectResponseType"> <xs:complexContent> <xs:restriction base="ConsumerSubjectResponseType"> <xs:sequence> <xs:element name="Sources" type="xs:string" minOccurs="0"/> <xs:element name="AdditionalOutputData" type="xs:string" minOccurs="0"/> </xs:sequence> </xs:restriction> </xs:complexContent> </xs:complexType> <xs:element name="Test"> <xs:complexType><xs:sequence> <xs:element name="A" type="ConsumerSubjectResponseType"></xs:element> <xs:element name="B" type="CombinedConsumerSubjectResponseType"></xs:element> </xs:sequence></xs:complexType> </xs:element> 

+4
source share
1 answer

Can this be done in xsd?

In your example: no or not.

Types obtained by restriction should repeat all the components of the particles, but attributes should not be repeated in the definition of a derived type, they are inherited from the base type. Removing the attribute required from the restricted type is not possible. You can specify a specific fixed (possibly empty) value for the required attributes and optional attributes that you could remove using use="prohibited" .

Usually, what you are trying to do is in some way the opposite, because "members of type A, the definition of which is a restriction of the definition of another type, B are always members of type B" and "A is a definition of a complex type that allows you to add the contents of an element or attribute in addition to that permitted by the other specified type definition, it is an extension of "(citations from W3C definition 1 , 2 ).

Solution 1, use xs:extension instead

Create a ConsumerSubjectResponseType as a base type and infer CombinedConsumerSubjectResponseType from it by extension.

 <xs:complexType name="CombinedConsumerSubjectResponseType-base"> <xs:sequence> <xs:element minOccurs="0" name="Sources" type="xs:string" /> <xs:element minOccurs="0" name="AdditionalOutputData" type="xs:string" /> </xs:sequence> </xs:complexType> <xs:complexType name="ConsumerSubjectResponseType-extension"> <xs:complexContent> <xs:extension base="CombinedConsumerSubjectResponseType-base"> <xs:sequence> <xs:element minOccurs="0" name="CustomerReferenceNumber" type="xs:string" /> </xs:sequence> <xs:attribute name="subjectIdentifier" type="xs:string" use="required" /> </xs:extension> </xs:complexContent> </xs:complexType> 

The problem with this solution is that the order of the elements of the extended type is changed from your original type definition. The <Sources> and <AdditionalOutputData> elements are displayed before the <CustomerReferenceNumber> element. The reason for this is that the base type and additional definitions are considered as two children of the sequential group, and the base type is added first.

Solution 2, use xs:group containing common elements

Define the sequence in CombinedConsumerSubjectResponseType as a group. You can then create the CombinedConsumerSubjectResponseType type simply by accessing this group. In the ConsumerSubjectResponseType you add the necessary new elements and attributes to the correct places, and also refer to this group.

 <xs:group name="CombinedConsumerSubjectResponse-group"> <xs:sequence> <xs:element minOccurs="0" name="Sources" type="xs:string" /> <xs:element minOccurs="0" name="AdditionalOutputData" type="xs:string" /> </xs:sequence> </xs:group> <xs:complexType name="ConsumerSubjectResponseType-group"> <xs:sequence> <xs:element minOccurs="0" name="CustomerReferenceNumber" type="xs:string" /> <xs:group ref="CombinedConsumerSubjectResponse-group" /> </xs:sequence> <xs:attribute name="subjectIdentifier" type="xs:string" use="required" /> </xs:complexType> <xs:complexType name="CombinedConsumerSubjectResponseType-group"> <xs:group ref="CombinedConsumerSubjectResponse-group" /> </xs:complexType> 

In this case, changes affecting both types should be made in the group, not in the types.

+4
source

Source: https://habr.com/ru/post/1339598/


All Articles