1
votes

I have a schema that has a local complexType element as follows.

<xs:complexType name="AddressType">
    <xs:sequence>
        <xs:element name="Line1" type="xs:string" minOccurs="0"/> 
        <xs:element name="Line2" type="xs:string" minOccurs="0" maxOccurs="100"/>
        <xs:element name="Location" minOccurs="0" maxOccurs="100">
            <xs:complexType>
                <xs:sequence>
                    <xs:element name="XCoordinate" type="xs:decimal" minOccurs="0"/>
                    <xs:element name="YCoordinate" type="xs:decimal" minOccurs="0"/>
                </xs:sequence>
            </xs:complexType>
        </xs:element>
    </xs:sequence> 
</xs:complexType>

I am trying to extend this complexType as follows

<xs:complexType name="InternalAddressType">
    <xs:complexContent>
        <xs:restriction base="AddressType">
            <xs:sequence>
                <xs:element name="Location" >
                </xs:element>
            </xs:sequence>
        </xs:restriction>
    </xs:complexContent>
</xs:complexType>

I am getting the following error

**Error for type 'InternalAddressType'.  The particle of the type is not a valid restriction of the particle of the base.

Can anyone please help me understand what am I doing worng. It seems that the problem is that the Location is a local ComplexType. But I can not change that since I am getting the xsd from the client and need to extend just the Loaction. How can I solve this situation. Any other suggestions are welcome.

2

2 Answers

0
votes

You're right: You can't restrict Location because it is defined by a local complexType.

Even a restriction of AddressType that includes the exact same components will fail similarly:

  <xs:complexType name="InternalAddressType">
    <xs:complexContent>
        <xs:restriction base="AddressType">
          <xs:sequence>
            <xs:element name="Line1" type="xs:string" minOccurs="0"/> 
            <xs:element name="Line2" type="xs:string" minOccurs="0" maxOccurs="100"/>
            <xs:element name="Location" minOccurs="0" maxOccurs="100">
              <xs:complexType>
                <xs:sequence>
                  <xs:element name="XCoordinate" type="xs:decimal" minOccurs="0"/>
                  <xs:element name="YCoordinate" type="xs:decimal" minOccurs="0"/>
                </xs:sequence>
              </xs:complexType>
            </xs:element>
          </xs:sequence>
        </xs:restriction>
    </xs:complexContent>
  </xs:complexType>

Without the attempt to override Location, the above definition would be fine.

Given that you cannot change AddressType to pull out the local complexType, what can you do? Depending upon your requirements, perhaps you might extend AddressType using xs:extension and define your own MyLocation element that is as you wish, ignoring the original Location element (or never creating it -- it's optional). Or, perhaps a fully decoupled definition of InternalAddressType works for you. If neither of these possibilities satisfy your purposes, state in the comments the requirements of your final goal, and perhaps we can find something suitably close.

0
votes

If you are able to use XSD 1.1 (sadly, not many people are), then you can define your restriction in the form of an assertion - which because it states precisely what additional conditions you want to apply, is a much more usable mechanism, in my opinion, than providing an alternative content model that has to maintain a close correspondence to the original.

XSD 1.1 is currently implemented in Saxon and Xerces.

The other solution is two-phase validation. Use the client's schema to ensure that the document conforms to the constraints defined by the client, then use your own schema (or other technology) to validate that it conforms to the additional constraints defined by you. That may well be an architecturally cleaner approach anyway.