0
votes

I would like to create an XSD file which can check if an attribute is present of not based on the name of its parent node. Any idea how I could do that? Below is an example of what I am trying to do.

Xml - AttrA and AttrB are required because the parent node is "A"

<A>
 <B AttrA="1" AttrB="2" />
</A>

Xml - AttrB and AttrC are required because the parent node is "C"

<C>
 <B AttrB="2" AttrC="3" />
</C>
1

1 Answers

1
votes

The simplest way to do this is to make one or both of the forms of B local to the complex type of its parent. If A and C are both top-level elements, and we make both forms of B local, for example, you might write:

<xs:element name="A">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="B" type="B-in-A"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

<xs:element name="C">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="C" type="B-in-C"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

The two types B-in-A and B-in-C are declared however you like, e.g.

<xs:complexType name="B-in-A">
  <xs:sequence/>
  <xs:attribute name="AttrA" type="xs:integer"/>
  <xs:attribute name="AttrB" type="xs:integer"/>
</xs:complexType>

<xs:complexType name="B-in-C">
  <xs:sequence/>
  <xs:attribute name="AttrB" type="xs:integer"/>
  <xs:attribute name="AttrC" type="xs:integer"/>
</xs:complexType>

In some contexts, you may want to declare a generic type for B and derive the two types B-in-A and B-in-C from it, so that they have some sort of genetic relation to each other; it depends on whether you have way to exploit such derivation relations.

In XSD 1.1, you also have the option of declaring B with a required AttrB and optional AttrA and AttrC, and then putting assertions on the types of A and C to check that a B inside an A carries AttrA and not AttrC, and the converse for a B inside a C.

Which of these feels clearer and simpler may depend on whether you think of the difference in the attributes of B as (a) a difference in the behavior of B based on its context, or (b) a constraint on A and/or C that takes the form of requiring a particular form for its child.