I have a XSD file (that I can't modify) that defines an attributeGroup like the one below
<xs:attributeGroup name="myAttributes">
<xs:attribute name="name" type="name_t" use="required"/>
<xs:attribute name="age" type="age_t" use="required"/>
</xs:attributeGroup>
Say, I want this attributeGroup to have another attribute called "gender". Since I can't modify this xsd, I define a new XSD and include this XSD there. But how do I add this new attribute to the myAttributes group?
So there are 2 options.
Option A is the simplest way of doing this, which is to include or import the first XSD into your second XSD and just include the first attribute group in a new attribute group that you've defined.
For Option A, here's the full XML of both XSDs and example XML:
First.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:attributeGroup name="myAttributes">
<xs:attribute name="name" type="name_t" use="required"/>
<xs:attribute name="age" type="age_t" use="required"/>
</xs:attributeGroup>
<xs:simpleType name="name_t">
<xs:restriction base="xs:string"/>
</xs:simpleType>
<xs:simpleType name="age_t">
<xs:restriction base="xs:int"/>
</xs:simpleType>
</xs:schema>
Second.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:include schemaLocation="First.xsd"/>
<xs:attributeGroup name="extendedMyAttributes">
<xs:attributeGroup ref="myAttributes"/>
<!-- New attribute -->
<xs:attribute name="gender" type="xs:string"/>
</xs:attributeGroup>
</xs:schema>
And now you can use the new, extended attribute group in an element definition:
<xs:element name="person">
<xs:complexType>
<xs:attributeGroup ref="extendedMyAttributes"/>
</xs:complexType>
</xs:element>
Example XML would then look like:
<?xml version="1.0" encoding="UTF-8"?>
<person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Second.xsd"
gender="male" name="Adam" age="20">
</person>
And this would validate fine.
Option B would be to override the existing definition of the myAttributes attribute group without creating a new attribute group with a new name, using the <xs:override>
element. This allows you to keep referring to the attribute group as myAttributes, instead of a new name.
Here's the schema for overriding myAttributes.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:override schemaLocation="First.xsd">
<xs:attributeGroup name="myAttributes">
<xs:attribute name="name" type="name_t"/>
<xs:attribute name="age" type="age_t"/>
<!-- New gender attribute -->
<xs:attribute name="gender" type="xs:string"/>
</xs:attributeGroup>
</xs:override>
<xs:element name="person">
<xs:complexType>
<xs:attributeGroup ref="myAttributes"/>
</xs:complexType>
</xs:element>
</xs:schema>
Because you're only adding a new attribute to the existing group (and keeping the attributes of the first group), simply creating a new attribute group that includes the first should suffice.
Comparing both options, Option A is also 'safer', in the sense if a new version of the first schema gets updated, you can refer to the updated XSD and retain any new or updated attributes from the original attribute group. With Option B you have to copy the name
and age
attributes in your overrided attribute group definition in addition to the new gender
attribute.
You would want to override things when you want to do things like completely rename, remove attributes etc. The only thing that basically remains the same is the name of the attribute group.
You can read more about override: https://www.w3.org/TR/xmlschema11-1/#override-schema, but I would recommend just going with Option A.