tags:

views:

13

answers:

1

i have scenario where have to restrict few elements from the complextype element when referred. For example below element AD when referred in ADConfig, i want only elements domainName,userName,password to be referred not hostName, portNumber.

    <element name="AD">
        <complexType>
            <sequence>
                <element name="hostName" type="string"/>
                <element name="portNumber" type="string"/>
                <element name="domainName" type="string"/>
                <element name="userName" type="string"/>
                <element name="password" type="string"/>
            </sequence>
        </complexType>
    </element>

    <element name="ADConfig">
    <complexType>
        <sequence>
            <element ref="tns:AD"/>
        </sequence>
    </complexType>
</element>
A: 

In terms of instance documents I think you are saying that you want AD elements which are child of ADConfig elements to consist only of a sequence of domainName, userName and passsword. Elsewhere, in this instance document you could have an AD element which had all five children listed above.

Assuming that I have this correct, I'm afraid that your exact requirement is simply not possible in the current version of XSD. I believe that XML Schema 1.1 may resolve your problem. However, if it's possible to rewrite your schema slightly then this becomes possible. By creating two complex types, you can have two models for the elements with the same name (in different contexts). For example,

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="unqualified">


    <xs:complexType name="ADType1">
        <xs:sequence>
            <xs:element name="hostName" type="xs:string"/>
            <xs:element name="portNumber" type="xs:string"/>
            <xs:element name="domainName" type="xs:string"/>
            <xs:element name="userName" type="xs:string"/>
            <xs:element name="password" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="ADType2">
        <xs:sequence>
            <xs:element name="domainName" type="xs:string"/>
            <xs:element name="userName" type="xs:string"/>
            <xs:element name="password" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>


    <xs:element name="ADTest">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="ADConfig1"/>
                <xs:element ref="ADConfig2"/>
                </xs:sequence>
        </xs:complexType>
    </xs:element>


    <xs:element name="ADConfig1">
        <xs:complexType>
            <xs:sequence>
                <xs:element type="ADType1" name="AD"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="ADConfig2">
        <xs:complexType>
            <xs:sequence>
                <xs:element type="ADType2" name="AD"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>


</xs:schema>

The above has two models ADType1 and ADType2 each of which can be used to declare an element named AD. In your situation, you could create a global type for AD which is used within the ADConfig element and a different type which could be used elsewhere.

If you can't use this sort of model (perhaps the type for AD is defined elsewhere and fixed), you may be able to utilise Schematron annotations to provide the same sort of rules driven validation that is going to be provided by XML Schema 1.1

Nic Gibson