0
votes

I am trying to write an XML Schema for validating the line characteristics described by the following XML code:

<linecharacteristics>
   <characteristic name = "color" value = "red" />
   <characteristic name = "style" value = "dashed" />
   ...
   <characteristic name = "thickness" value = "medium" />
</linecharacteristics>

There are multiple characteristics and this is the XML Schema code that I have so far:

<xs:element name="linecharacteristics">
  <xs:complexType>
    <xs:sequence>
        <xs:element name="characteristic" minOccurs="0" maxOccurs="unbounded">
            <xs:complexType>
                <xs:attribute name="name" type="xs:string" use="required"/>
                <xs:attribute name="value" type="xs:string" use="required"/>
            </xs:complexType>
        </xs:element> 
    </xs:sequence>
  </xs:complexType>
</xs:element>

What I am trying to figure out is how to check whether the attributes are correct. For example, the "name" attribute can say 'color', 'style', and 'thickness' but not 'shape'. Also, if the attribute "name" says 'color', then the "values" can only contain 'red', 'yellow', 'green' and not 'dashed'; 'dashed' value is only associated with the name 'style'. So how do I define what are the acceptable attribute value sets?

Thanks for your help!

2

2 Answers

2
votes

If you are using XSD 1.1 you can manage this with assertions. If you are using XSD 1.0, you'll need to use something like Schematron or code the constraints directly in a conventional programming language. Using XSD 1.1 you could write your complex type as:

<xs:element name="linecharacteristics">
    <xs:complexType>
       <xs:sequence>
           <xs:element name="characteristic" minOccurs="0" maxOccurs="unbounded">
               <xs:complexType>
                   <xs:attribute name="name" type="xs:string" use="required"/>
                   <xs:attribute name="value" type="xs:string" use="required"/>
               </xs:complexType>
           </xs:element> 
       </xs:sequence>
       <xs:assert test="(
           (@name = 'color') and @value = ('red', 'green', 'yellow') or
           (@name = 'style') and @value = ('dashed')
           )"></xs:assert>

    </xs:complexType>
</xs:element>
0
votes

You can only partially do what you are asking with schema validation. You can check that the name contains the correct values, but you can't tell it to check that the value matches the name given the structure you've outlined (see below). To validate that they match sets you would have to use XSLT/Business Rules/Custom Code.

    <xs:element name="linecharacteristics">
      <xs:complexType>
        <xs:sequence>
          <xs:element minOccurs="0" maxOccurs="unbounded" name="characteristic">
            <xs:complexType>
              <xs:attribute name="name" use="required">
                <xs:simpleType>
                  <xs:restriction base="xs:string">
                    <xs:enumeration value="color" />
                    <xs:enumeration value="style" />
                    <xs:enumeration value="thickness" />
                  </xs:restriction>
                </xs:simpleType>
              </xs:attribute>
              <xs:attribute name="value" use="required">
                <xs:simpleType>
                  <xs:restriction base="xs:string">
                    <xs:enumeration value="red" />
                    <xs:enumeration value="yellow" />
                    <xs:enumeration value="green" />
                    <xs:enumeration value="dashed" />
                    <xs:enumeration value="medium" />
                  </xs:restriction>
                </xs:simpleType>
              </xs:attribute>
            </xs:complexType>
          </xs:element>
        </xs:sequence>
      </xs:complexType>
    </xs:element>