- From: Jeni Tennison <jeni@jenitennison.com>
- Date: Mon, 25 Feb 2002 09:34:25 +0000
- To: Lee Goddard <Home@LeeGoddard.com>
- CC: xmlschema-dev@w3.org
Hi Lee, > Section 2.2.3 ("Naming Conflicts") of XML Schema Part 0: Primer > seems to suggest to me that the only way I can define an element as > either one thing or another is by using different namespaces. > > Am I correct in thinking this or is there a more elegant solution? There is a more elegant solution, although it does involve changing the XML instances (but then, so would using different namespaces). The content and attributes of an element are its type, so what you're asking here is about saying that an element can either be one type or another type. You can do this by creating two, related, complex types; with your example, since the name element has to come first, I think that easiest way is to create an abstract type that allows both a name attribute and a name child element, and then restrict it to make the two types that you actually want, as follows: <xs:complexType name="abstractListType" abstract="true"> <xs:sequence> <xs:element name="name" type="xs:string" minOccurs="0" /> <xs:element name="data" type="xs:string" /> </xs:sequence> <xs:attribute name="name" type="xs:string" /> </xs:complexType> <xs:complexType name="attributeListType"> <xs:complexContent> <xs:restriction base="generalListType"> <xs:sequence> <xs:element name="data" type="xs:string" /> </xs:sequence> <xs:attribute name="name" type="xs:string" use="required" /> </xs:restriction> </xs:complexContent> </xs:complexType> <xs:complexType name="elementListType"> <xs:complexContent> <xs:restriction base="generalListType"> <xs:sequence> <xs:element name="name" type="xs:string" /> <xs:element name="data" type="xs:string" /> </xs:sequence> <xs:attribute name="name" type="xs:string" use="prohibited" /> </xs:restriction> </xs:complexContent> </xs:complexType> When you define the list element, give it the abstract type as its type: <xs:element name="list" type="abstractListType" /> Now, the list element in the instance cannot actually be of the abstract list type because it's abstract, so it must be of one of the derived types. For each list element in the instance, you have to indicate the type of list it is, using the xsi:type attribute, for example: <list xsi:type="elementListType"> <name>foo</name> <data>bar</data> </list> or <list xsi:type="attributeListType" name="foo"> <data>bar</data> </list> You could do a similar thing, but changing the names of the elements, using substitution groups, but I imagine that that's not an option (since if they could have different names there wouldn't be this problem anyway). If you can't change the instances by adding xsi:type attributes, then I don't think that there's a way to articulate the constraint using XML Schema. In that case, you should make the abstract type non-abstract, and use that as the list type, and write the other constraints in another way (e.g. using Schematron rules, a RELAX NG grammar or just in natural language documentation as you would with a DTD). Cheers, Jeni --- Jeni Tennison http://www.jenitennison.com/
Received on Monday, 25 February 2002 04:34:28 UTC