Я думаю, что это идеальная ситуация для использования элемента xs: group: если вы оберните его вокруг своего элемента и сделаете его необязательным (при этом содержимое этого элемента обязательно), вы получите желаемый эффект.
<xs:group name="pets_group">
<xs:element name="pets" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:choice>
<xs:sequence>
<xs:element name="cat"/>
<xs:element name="dog" minOccurs="0"/>
</xs:sequence>
<xs:sequence>
<xs:element name="dog"/>
<xs:element name="cat" minOccurs="0"/>
</xs:sequence>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:group>
Тогда вместо использования элемента pets используйте группу pets_group:
<xs:element name="root">
<xs:complexType>
<xs:group ref="pets_group"/>
</xs:complexType>
</xs:element>
Наличие выбора между кошкой, за которой следует дополнительная собака, и собакой, за которой следует дополнительная кошка, гарантирует, что в теге домашних животных будет что-то . Отсутствие тега домашних животных позволяет вам не указывать ни одного домашнего животного.
В качестве альтернативы, вы можете определить их вместе, просто "вставив" ссылку на группу. Это, вероятно, то, что вы хотите сделать, если тег домашних животных используется только в одном месте.