1

I have a rather simple XML structure;

<list... >
    <members>
        <person type="NAME_WITH_A">
            <name>Ada</name>
        </person>
        <person type="NAME_WITH_B">
            <name>Berta</name>
        </person>
    </members> 
</list>

I want to restrict the value of 'name' to a certain set of names, depending on the value of the attribute 'type' of element 'person'.

So, for example, if <person type="NAME_WITH_A">, only the names

  • Anna
  • Ada
  • Amanda

should be valid as , if <person type="NAME_WITH_B">, only

  • Berta,
  • Bob
  • Bret

should be valid values for the <name> element.

According to this question i created the following Schema:

<xs:schema xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1"  xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="list">
</xs:element>

<xs:element name="person">
    <xs:complexType>
        <xs:sequence>
            <xs:element ref="name"/>
        </xs:sequence>
        <xs:attribute name="type" use="required">
            <xs:simpleType>
                <xs:restriction base="xs:string">
                    <xs:enumeration value="NAME_WITH_A"/>
                    <xs:enumeration value="NAME_WITH_B"/>
                </xs:restriction>
            </xs:simpleType>
        </xs:attribute>
    </xs:complexType>
</xs:element>

<xs:element name="name">
    <xs:alternative test="@type='NAME_WITH_A'" type="choice_names_A"/>
    <xs:alternative test="@type='NAME_WITH_B'" type="choice_names_B"/>  
    <xs:alternative type="xs:error"/>
</xs:element>

<xs:element name="members">
    <xs:complexType>
        <xs:sequence>
            <xs:element ref="person" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>

<xs:simpleType name="choice_names_A">
    <xs:restriction base="xs:string">
        <xs:enumeration value="Anna"/>
        <xs:enumeration value="Ada"/>
        <xs:enumeration value="Amanda"/>
    </xs:restriction>
</xs:simpleType>
<xs:simpleType name="choice_names_B">
     <xs:restriction base="xs:string">
        <xs:enumeration value="Berta"/>
        <xs:enumeration value="Bob"/>
        <xs:enumeration value="Bret"/>
    </xs:restriction>
</xs:simpleType>
</xs:schema>

which does not really work for me. I have the feeling, that, as I refer in test="@type='NAME_WITH_A'" to the @type attribute of ANOTHER element, it is always false.

I also tried test="list / members / person / @type='NAME_WITH_A'" but with no success.

LocalHorst
  • 1,048
  • 2
  • 11
  • 24

1 Answers1

1

You have the right idea in using Conditional Type Assignment, but you're applying it to the wrong element. Instead of applying it to name, you have to apply it to person (the element whose type will vary according to the type attribute). From there, you can vary the content model of person to have name elements of differing types.

See also How to make type depend on attribute value using Conditional Type Assignment.

kjhughes
  • 106,133
  • 27
  • 181
  • 240