Search code examples
xmlxsdxsd-validationxsd-1.1

How to check if attribute value is A then attribute B is compulsory else other attribute is coming next in xsd 1.1?


Recently I was working on xsd 1.1 and I came across a situation where I need to check if attribute 'network_mode' has value 'Periodic' then another attribute 'periodic_interval' is compulsory to be filled by xml user.

I tried with assertion but I am confused with it. I don't know how to use it in xsd.

My xml

<profile network_mode="Periodic" periodic_interval="3600" sample_size="250">"Gyroscope"</profile>

and My XSD

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="urn:Test.Namespace" xmlns="urn:Test.Namespace"
elementFormDefault="qualified" 
attributeFormDefault="unqualified" 
vc:minVersion="1.1" xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning">
...
<xsd:attribute name="network_mode" use="required">
    <xsd:simpleType>
        <xsd:restriction base="xsd:string">
            <xsd:enumeration value="Periodic" />
                <xsd:enumeration value="Real-Time" />
         </xsd:restriction>
    </xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="periodic_interval">
    <xsd:simpleType>
        <xsd:restriction base="xsd:nonNegativeInteger">
            <xsd:assertion test="if (@network_mode = 'Periodic' and not(exists(@periodic_interval)) ) then false() else true()" />      
        </xsd:restriction>
    </xsd:simpleType>   
</xsd:attribute>
...

Here it gives me error at assertion. I am using XSD 1.1.

Any workaround? Any help will be appreciated. Thank you.


Solution

  • You can do it either with assertions or with conditional type assignment.

    With assertions:

    test="not(@network_mode='Periodic') or exists('periodic_interval')" 
    

    Or you may find the inversion more intuitive:

    test="not(@network_mode='Periodic' and not(exists('periodic_interval')))
    

    With conditional type assignment, you write a set of xs:alternative elements that assign one type (with a mandatory attribute) if the attribute has one value, and a different type (with an optional attribute) if it has a different value.