问题
I would like to ask if this is possible and if yes, how to achieve it:
For example if I have an element definition with a complexType in an XML schema definition like this:
<xsd:element name="tag" type="tag"/>
<xs:complexType name="tag">
<xs:choice maxOccurs="unbounded">
<xs:element name="subtag" type="subtag"/>
<xs:element name="another_subtag" type="another_subtag"/>
<xs:element name="another_subtag_2" type="another_subtag_2"/>
</xs:choice>
<xs:attribute name="type" type="attr_type"/>
<xs:attribute name="an_attr" type="an_attr"/>
<xs:attribute name="another_attr" type="another_attr"/>
</xs:complexType name="attr_type">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="type_1"/>
<xsd:enumeration value="type_2"/>
<xsd:enumeration value="type_3"/>
</xsd:restriction>
<xsd:simpleType/>
1) Is it possible to make the attribute 'an_attr' of the tag element required only if the tag element has the attribute 'attr_type' set to 'type_2'?
And another question: 2) Is it possible to make the complexType 'tag' contain different child elements based again e.g. on the value of the 'attr_type'? For example for:
<tag attr_type="type_1">
have only this childs:
<xs:element name="subtag" type="subtag"/>
And for:
<tag attr_type="type_2">
have only childs:
<xs:element name="another_subtag" type="another_subtag"/>
OR
<xs:element name="another_subtag_2" type="another_subtag_2"/>
?
If it is possible, how can I achieve this?
Thanks for the attention!
EDIT: As I saw here -> https://blogs.oracle.com/rammenon/entry/xml_schema_11_what_you_need_to In the example number 22 (in Conditional Type Assignments), could it be done in such a way?
<!--inline alternative type definitions -->
<element name="TimeTravel" type="TravelType">
<alternative test="@direction='Future'">
<complexType>
<complexContent>
<restriction base="TravelType"
....
<!-- some past travel related elements go here -->
</complexType>
</alternative>
<alternative test="@direction='Past'">
<complexType>
<complexContent>
<restriction base="TravelType"
....
<!-- some future travel related elements go here -->
</complexType>
</alternative>
</element>
OR
<!--Named alternative type definitions -->
<element name="TimeTravel" type="TravelType">
<alternative test="@direction='Future' type="FutureTravelType"/>
<alternative test="@direction='Past' type="PastTravelType"/>
</element>
As I understood it, TimeTravel element can have different complexTypes based on the direction attribute value, am I correct? But it says that XSD 1.1 must be used. Can I use this rules inside my XML Schema?
回答1:
Let's try again, since my answer has been disputed, it's probably best to give it again in more detail. Editing my original answer would make the subsequent comments incomprehensible and only add confusion.
Question 1: Is it possible to make the attribute 'an_attr' of the tag element required only if the tag element has the attribute 'attr_type' set to 'type_2'?
Answer 1: yes. You can do it like this (tested; modified from the original to avoid reference to irrelevant and undefined types):
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="tag" type="tagType">
<xs:alternative test="@attr_type='type_2'" type="tagTypeWithMandatoryAttr"/>
</xs:element>
<xs:complexType name="tagType">
<xs:choice maxOccurs="unbounded">
<xs:element name="subtag" type="xs:anyType"/>
<xs:element name="another_subtag" type="xs:anyType"/>
<xs:element name="another_subtag_2" type="xs:anyType"/>
</xs:choice>
<xs:attribute name="type" type="xs:string"/>
<xs:attribute name="an_attr" type="xs:string"/>
<xs:attribute name="another_attr" type="xs:string"/>
</xs:complexType>
<xs:complexType name="tagTypeWithMandatoryAttr">
<xs:complexContent>
<xs:restriction base="tagType">
<xs:choice maxOccurs="unbounded">
<xs:element name="subtag" type="xs:anyType"/>
<xs:element name="another_subtag" type="xs:anyType"/>
<xs:element name="another_subtag_2" type="xs:anyType"/>
</xs:choice>
<xs:attribute name="type" type="xs:string"/>
<xs:attribute name="an_attr" type="xs:string" use="required"/>
<xs:attribute name="another_attr" type="xs:string"/>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
</xs:schema>
Question 2:
Is it possible to make the complexType 'tag' contain different child elements based again e.g. on the value of the 'attr_type'?
Answer 2:
Yes, for example (similarly tested):
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="tag" type="xs:anyType">
<xs:alternative test="@attr_type='type_2'" type="tagType1"/>
<xs:alternative type="tagType2"/>
</xs:element>
<xs:complexType name="tagType1">
<xs:choice maxOccurs="unbounded">
<xs:element name="subtag" type="xs:anyType"/>
<xs:element name="another_subtag" type="xs:anyType"/>
<xs:element name="another_subtag_2" type="xs:anyType"/>
</xs:choice>
</xs:complexType>
<xs:complexType name="tagType2">
<xs:choice maxOccurs="unbounded">
<xs:element name="subtag" type="xs:anyType"/>
<xs:element name="another_subtag" type="xs:anyType"/>
<xs:element name="another_subtag_2" type="xs:anyType"/>
</xs:choice>
</xs:complexType>
</xs:schema>
Question 0: Is it possible to define an attribute of an XML element (E) to be required only if another element (F)'s attribute is set to a particular value?
Answer 0: it depends on the relationship of the two elements E and F. If F is an ancestor of E, then it can be done using conditional type assignment in the declaration of F. If E and F are siblings or more remotely related, then it cannot be done using conditional type assignment, but it can be done using an assertion attached to the common ancestor of E and F.
回答2:
It's possible in XSD 1.1 using the new feature of "conditional type assignment". This allows you to define the type of an element as a function of the values of its attributes.
XSD 1.1 is implemented in Altova, Saxon, and Xerces.
回答3:
No, because conditional type assignment (mentioned in the other answer) only assigns a type to an element. Hence the name, conditional type assignment. Furthermore, when using conditional type assignment the element's type is determined by its own attributes and not the attributes of some other element.
Even using an XPATH expression with conditional type assignment, you can only access the attributes of the element being validated. It cannot access its parent or ancestors, and it cannot even access its children or descendants like assertions can.
[EDIT] The main question, as posted, asked if the 1st attribute can be required based on another element's attribute's, the answer to that is no.
This would required a much higher level of validation than can be done with XML Schema 1.1. Maybe Schematron ??? I don't know. Sometimes the answer isn't what you want to hear.
Reference: Definitive XML Schema by Priscilla Walmsley, 2nd edition, page 378-379.
Here is a great post that sums up the countless times questions like this have been asked about XML validation. The new additions in Schema 1.1 are very limited in scope.
来源:https://stackoverflow.com/questions/25067873/is-it-possible-to-define-an-attribute-of-an-xml-element-to-be-required-only-if-a