- From: Michael Rossi <mrossi@csc.com>
- Date: Wed, 7 Aug 2002 11:43:04 -0400
- To: xmlschema-dev@w3.org
Thanks Eddie, that certainly was helpful. I'm not sure it's the right approach in my situation, but it definitiely improves my understanding of how to use substitution groups! :-) I should have provided more context for my question, though. So to elaborate, the parameter structure I described earlier will be contained in an Operation element that has Type and Name attributes: <Operation Type="" Name=""> <Parameters> <Parameter Name="" Type="" Direction=""> <Value></Value> </Paramater> </Parameters> </Operation> We'll send these requests to different handlers based on the type of operation (a couple of internal types and an external interface type). So if the request is for one of our internal processes the handler will expect to extract the parameters as shown. However if the operation type is an external interface, then its Name will also be used to route the request to a dedicated handler for that interface. This implies a completely different functional thread than the simpler processes we would perform internally, so it's very likely that the external interface would require it's own complete schema. So instead of "Parameters", at this point I should drop in whatever data is appropriate to the specified interface. This data would be passed on to the appropriate handler, which would know how to deal with it. I suppose this is analogous to a SOAP body containing a custom encoding. (Duh, maybe I should go look at how the SOAP spec addresses this right? :-) I may in fact end up using SOAP to envelope this, but I'd still have to provide most of what we're developing. Michael A. Rossi Computer Sciences Corporation mailto:mrossi@csc.com 856-983-4400 x4964 Eddie Robertsson <erobertsson@allet te.com.au> 08/06/2002 09:54 PM Hi Michael, >I'm a relative newbie to XSDL (but an experienced markup developer), >so kindly excuse my ignorance if it should rear it's ugly head. I'm >developing a system interface schema and we'd like to leverage XSDL's >potential for datatype validation. For "internal" processes we have a >generic structure containing parameters, where each parameter has >attributes for name, type and direction (essentially name/value pairs). >Like so: > ><parameter name="input1" datatype="Int" direction="In"> > <value>1</value> ></parameter> ><parameter name="output1" datatype="Int" direction="Out"> > <value>2</value> ></parameter> > > This is fine for our puposes, but when we add external interfaces into the >mix we'll need to support more complex data exchange requirements. Most >likely, each interface will use its own schema, which can't be shoe-horned >in to our parameter structure (mostly because they'll want to validate >their datatypes at the parser level). While this is unavoidable, I'd prefer >that every interface used the rest of our mesasge framework so that we can >standardize on ways to handle things like authentication information. So >I'm considering doing something in my schema like (pseudo-spec): > ><choice> > <!element name="parameters"/> > <any namespace=""##other"/> ></choice> > >Any thoughts on whether this would be good, bad, done better some other way >would be most appreciated. TIA. > I guess this depends on how much control you want to have over the external interfaces that can be added. If you use <xs:any> you don't really have any control at all and the external interfaces can pretty much add whatever they want. For more control I think this is a good use-case for substitutionGroups which allows one element to serve as a model in your schema and then the external interfaces could define their own "parameter" elements that can be used instead of the model. The base schema would contain the complexType that serves as the base type for the parameter-model element as well as the structure of your main schema. To illustrate I will use the following example: Base schema: -------------- <?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:element name="Root"> <xs:complexType> <!-- This is the content model that defines the parameter elements. Instead of having a choice between "parameter" and "any" this is now zero-or-more parameterModel elements. --> <xs:sequence> <xs:element ref="parameterModel" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> <!-- The "parameterModel" element is declared as abstract which means that it cannot by itself appear in an instance document. Instead one of the elements that are defined in the substitutionGroup for "parameterModel" must appear in the instance document. --> <xs:element name="parameterModel" type="parameterBase" abstract="true"/> <!-- Define the base type for the elements that can substitute the parameterModel element so that they at least must contain a "name" attribute. --> <xs:complexType name="parameterBase"> <xs:attribute name="name" use="required" type="xs:string"/> </xs:complexType> <!-- Define the type for the local parameter element. This type must be derived from the "parameterBase" type so that any element of this type can be used instead of the "parameterModel" element. --> <xs:complexType name="myParameterType"> <xs:complexContent> <xs:extension base="parameterBase"> <xs:sequence> <xs:element name="value" type="xs:string"/> </xs:sequence> <xs:attribute name="datatype" type="xs:string" use="required"/> <xs:attribute name="direction" type="xs:string" use="required"/> </xs:extension> </xs:complexContent> </xs:complexType> <!-- Finally we define the local parameter element that can appear instead of the "parameterModel" in the instance document. This element is defined to be in the substitutionGroup of the "parameterModel" element.--> <xs:element name="myParameter" type="myParameterType" substitutionGroup="parameterModel"/> </xs:schema> Now, if only the above schema was used then an instance document could look like this (Note that the "myParameter" element is used instead of the "parameterModel" element.): <?xml version="1.0" encoding="UTF-8"?> <Root> <myParameter name="input1" datatype="Int" direction="In"> <value>1</value> </myParameter> <myParameter name="output1" datatype="Int" direction="Out"> <value>2</value> </myParameter> </Root> Now to extend this with an external interface that will define its own parameter element this can be done in a separate schema that will include the base schema. Here is an example: External schema: ----------------- <?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <!-- Include the base schema --> <xs:include schemaLocation="substGroup_base.xsd"/> <!-- This is the type definition for the external parameter elements. This type must also derive from the "parameterBase" type so that the elements with this type can be used instead of the "parameterModel" element.--> <xs:complexType name="externalParameterType"> <xs:complexContent> <xs:extension base="parameterBase"> <xs:sequence> <xs:element name="value" type="xs:string"/> <xs:element name="external" type="xs:string"/> </xs:sequence> <xs:attribute name="externalAtt" type="xs:string" use="required"/> </xs:extension> </xs:complexContent> </xs:complexType> <!-- The external parameter elements are declared in the substitutionGroup of the "parameterModel" element and can hence be used instead of this element in the instance document.--> <xs:element name="externalParameter" type="externalParameterType" substitutionGroup="parameterModel"/> </xs:schema> In this external schema we have defined a new type that defines the external parameter elements (here called "externalParameter"). Since these elements can be used instead of the "parameterModel" elements in the instance document an instance that conforms to this schema can look like this: <?xml version="1.0" encoding="UTF-8"?> <Root> <myParameter name="input1" datatype="Int" direction="In"> <value>1</value> </myParameter> <myParameter name="output1" datatype="Int" direction="Out"> <value>2</value> </myParameter> <externalParameter name="ext1" externalAtt="whatever"> <value>3</value> <external>55</external> </externalParameter> </Root> This is made possible becuase the externalParameter element is declared to be in the substitutionGroup of the parameterModel element. I'm not sure if this match your design criteria but it seems it would fit in well with your description above. The drawback with this method is that all the elements involved in the substitutionGroup must be declared as global elements. For more information on substitutionGroups see [1]. Hope this was of some help, Cheers, /Eddie [1] http://www.w3.org/TR/xmlschema-0/#SubsGroups
Received on Wednesday, 7 August 2002 11:44:09 UTC