[XML-DEV Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] Re: Schema definition of element with optional children
Hi Joe, There are a couple of possibilities. One is to use xsi:type in the instance document to specify if you have a deleted or inserted, etc. address. A sample schema and instance document look like below <?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> <xs:element name="address" type="addressType"> </xs:element> <xs:complexType name="addressType" abstract="true"/> <xs:complexType name="inserted"> <xs:complexContent> <xs:extension base="addressType"> <xs:sequence> <xs:element ref="addressLine1"/> <xs:element ref="addressLine2"/> <xs:element ref="city"/> <xs:element ref="postCode"/> <xs:element ref="country"/> </xs:sequence> </xs:extension> </xs:complexContent> </xs:complexType> <xs:complexType name="deleted"> <xs:complexContent> <xs:extension base="addressType"/> </xs:complexContent> </xs:complexType> <xs:element name="addressLine1"> <xs:complexType/> </xs:element> <xs:element name="addressLine2"> <xs:complexType/> </xs:element> <xs:element name="city"> <xs:complexType/> </xs:element> <xs:element name="postCode"> <xs:complexType/> </xs:element> <xs:element name="country"> <xs:complexType/> </xs:element> </xs:schema> <address xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="inserted"> <addressLine1/> <addressLine2/> <city/> <postCode/> <country/> </address> <address xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="deleted"/> Another possibility is to declare the address element abstract and make two elements, for instance insertedAddress and deletedAddress that can substitute address. For that change the <xs:element name="address" type="addressType" abstract="true"/> from the above schema with: <xs:element name="address" type="addressType" abstract="true"/> <xs:element name="insertedAddress" type="inserted" substitutionGroup="address"/> <xs:element name="deletedAddress" type="deleted" substitutionGroup="address"/> and in that case the sample instances will look like: <insertedAddress> <addressLine1/> <addressLine2/> <city/> <postCode/> <country/> </insertedAddress> <deletedAddress/> If you want to keep the instance exactly as it is then you can use Schematron embedded rules, below there is a sample schema and instances. <?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> <xs:element name="address"> <xs:annotation> <xs:appinfo> <pattern xmlns="http://www.ascc.net/xml/schematron" name="testAddress"> <rule context="address[@recordStatus='deleted']"> <assert test="count(*)=0">Deleted address should have no content.</assert> </rule> </pattern> </xs:appinfo> </xs:annotation> <xs:complexType> <xs:sequence> <xs:element ref="addressLine1"/> <xs:element ref="addressLine2"/> <xs:element ref="city"/> <xs:element ref="postCode"/> <xs:element ref="country"/> </xs:sequence> <xs:attribute name="recordStatus" use="required"> <xs:simpleType> <xs:restriction base="xs:NMTOKEN"> <xs:enumeration value="inserted"/> <xs:enumeration value="deleted"/> </xs:restriction> </xs:simpleType> </xs:attribute> </xs:complexType> </xs:element> <xs:element name="addressLine1"> <xs:complexType/> </xs:element> <xs:element name="addressLine2"> <xs:complexType/> </xs:element> <xs:element name="city"> <xs:complexType/> </xs:element> <xs:element name="postCode"> <xs:complexType/> </xs:element> <xs:element name="country"> <xs:complexType/> </xs:element> </xs:schema> <address recordStatus="inserted"> <addressLine1/> <addressLine2/> <city/> <postCode/> <country/> </address> <address recordStatus="deleted"/> for an invalid instance like: <address recordStatus="deleted"> <addressLine1/> <addressLine2/> <city/> <postCode/> <country/> </address> you will get SystemID: C:\george\workspace\oXygen\samples\test.xml Location: 1:0 Description: Deleted address should have no content. (count(*)=0) Best Regards, George --------------------------------------------------------------------- George Cristian Bina <oXygen/> XML Editor, Schema Editor and XSLT Editor/Debugger http://www.oxygenxml.com Joe Fawcett wrote: > Dear All > > I'm struggling to find the best way to restrict an element that holds > address data. > If the address is to be deleted it will look like this: > <address recordStatus="deleted"/> > > if it's new or an update it will be along the lines of: > > <address recordStatus="inserted"> > <addressLine1></addressLine1> > <addressLine2></addressLine2> > <city></city> > <postCode></postCode> > <country></country> > </address> > > with various fields being optional, these are UK addresses only. > > What's the most efficient way to declare this using XSD only as I > believe I can't say, "if recordStatus = 'deleted' then..." etc? > > I believe I have to give a choice of two types but this seems tedious? > > Thanks > > Joe > > > > ----------------------------------------------------------------- > The xml-dev list is sponsored by XML.org <http://www.xml.org>, an > initiative of OASIS <http://www.oasis-open.org> > > The list archives are at http://lists.xml.org/archives/xml-dev/ > > To subscribe or unsubscribe from this list use the subscription > manager: <http://www.oasis-open.org/mlmanage/index.php> >
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|