I have following schema
<complexType name="BookShelf">
<sequence>
<element name="newBook" type="string" minOccurs="0" maxOccurs="unbounded"/>
<element name="oldBook" type="string" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
</complexType>
XJC generates BookShelf class with two lists, one for newBook and one for oldBook. Excellent!
Now I want books to appear in any order. So I rewrite my schema to:
<complexType name="BookShelf">
<sequence>
<choice minOccurs="0" maxOccurs="unbounded">
<element name="newBook" type="string"/>
<element name="oldBook" type="string"/>
</choice>
</sequence>
</complexType>
But now XJC generates BookShelf with only one list newBookOrOldBook of type List<JAXBElement<String>>.
I don't care about the order in which books appear and I want to allow XML writer to specify books in any order he\she wishes, but I still want books of each type as List in generated BookShelf class. Is there any way I can achieve this?
You can use the Simplify plugin from JAXB2 Basics. It can simplify #XmlElements and #XmlElementRefs properties, which makes things a lot easier, if you don't really care about the order. Here's an example (excerpt from the documentation):
Consider the following choice:
<xs:complexType name="typeWithReferencesProperty">
<xs:choice maxOccurs="unbounded">
<xs:element name="a" type="someType"/>
<xs:element name="b" type="someType"/>
</xs:choice>
</xs:complexType>
This will normally generate a property like:
#XmlElementRefs({
#XmlElementRef(name = "a", type = JAXBElement.class),
#XmlElementRef(name = "b", type = JAXBElement.class)
})
protected List<JAXBElement<SomeType>> aOrB;
You can use the simplify:as-element-property element to remodel this complex property as two element properties or simplify:as-reference-property as two reference properties.
Not that in the case of a reference property, you have to customize one of the xs:element and not the xs:choice.
<xs:complexType name="typeWithReferencesProperty">
<xs:choice maxOccurs="unbounded">
<xs:element name="a" type="someType">
<xs:annotation>
<xs:appinfo>
<simplify:as-element-property/>
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="b" type="someType"/>
</xs:choice>
</xs:complexType>
Results in:
#XmlElement(name = "a")
protected List<SomeType> a;
#XmlElement(name = "b")
protected List<SomeType> b;
Maybe something like this?
<schema
elementFormDefault = "qualified"
xmlns = "http://www.w3.org/2001/XMLSchema"
xmlns:xs = "http://www.w3.org/2001/XMLSchema"
xmlns:tns = "urn:cheeso.examples.2009.05.listofbooks"
targetNamespace = "urn:cheeso.examples.2009.05.listofbooks"
>
<element name="Shelf" nillable="true" type="tns:BookShelf" />
<complexType name="BookShelf">
<sequence>
<element minOccurs="0" maxOccurs="1" name="Store" type="tns:ArrayOfChoice1" />
</sequence>
</complexType>
<complexType name="ArrayOfChoice1">
<choice minOccurs="0" maxOccurs="unbounded">
<element minOccurs="1" maxOccurs="1" name="newBook" nillable="true" type="tns:newBook" />
<element minOccurs="1" maxOccurs="1" name="oldBook" nillable="true" type="tns:oldBook" />
</choice>
</complexType>
<complexType name="Book">
<attribute name="name" type="string" />
</complexType>
<complexType name="newBook">
<complexContent mixed="false">
<extension base="tns:Book" />
</complexContent>
</complexType>
<complexType name="oldBook">
<complexContent mixed="false">
<extension base="tns:Book" />
</complexContent>
</complexType>
</schema>
Of course you could simplify to
<schema
elementFormDefault = "qualified"
xmlns = "http://www.w3.org/2001/XMLSchema"
xmlns:xs = "http://www.w3.org/2001/XMLSchema"
xmlns:tns = "urn:cheeso.examples.2009.05.listofbooks"
targetNamespace = "urn:cheeso.examples.2009.05.listofbooks"
>
<element name="Shelf" nillable="true" type="tns:BookShelf" />
<complexType name="BookShelf">
<sequence>
<element minOccurs="0" maxOccurs="1" name="Store" type="tns:ArrayOfChoice1" />
</sequence>
</complexType>
<complexType name="ArrayOfChoice1">
<choice minOccurs="0" maxOccurs="unbounded">
<element minOccurs="1" maxOccurs="1" name="newBook" nillable="true" type="xs:string" />
<element minOccurs="1" maxOccurs="1" name="oldBook" nillable="true" type="xs:string" />
</choice>
</complexType>
</schema>
I don't think this is possible in JAXB, without writing some custom java or XSLT.
JAXB isn't very good at mapping between objects and xml that have different structure, like yours. Also, the ordering of the old book with respect to new books in XML would be lost when converted to two separate lists in Java, and JAXB generally wants to preserve information.
The following does not answer your question, but maybe it's a step towards what you want:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="bookShelf" type="BookShelf"/>
<xs:complexType name="BookShelf">
<xs:sequence>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="newBook" minOccurs="0" type="xs:string"/>
<xs:element name="oldBook" minOccurs="0" type="xs:string"/>
</xs:sequence>
</xs:sequence>
</xs:complexType>
</xs:schema>
I haven't tried this with JAXB, but I think it will generate a list of a class with two fields, newBook and oldBook. So, you don't have to cast or use instanceof, but can just check for null to see which one it is. As I said, it's not a solution, but maybe a little bit closer.
I think I have to refuse the idea of mixing lists of different elements in one element (mixing old and new books on a bookself), especially because I'm planning to reference lists of those elements (new and old books lists) in other elements. If I don't it quickly became a nightmare in java code. I ended with the following schema:
<schema
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://www.example.org/books"
targetNamespace="http://www.example.org/books"
elementFormDefault="qualified"
>
<complexType name="BookShelf">
<sequence>
<element name="newBooks" type="tns:NewBookList" minOccurs="0" />
<element name="oldBooks" type="tns:OldBookList" minOccurs="0" />
</sequence>
</complexType>
<complexType name="NewBookList">
<sequence>
<element name="newBook" type="tns:NewBook" maxOccurs="unbounded" />
</sequence>
</complexType>
<complexType name="OldBookList">
<sequence>
<element name="oldBook" type="tns:OldBook" maxOccurs="unbounded" />
</sequence>
</complexType>
<complexType name="NewBook" />
<complexType name="OldBook" />
</schema>
Thanks everyone for helping me realize this. This schema will lead to more clear and simple Java code as well as to more readable and predictable XML document.
Related
is it possible to define the order of elements?
example
I have the following XML file
<input>
<action no="1" type="xyz"/>
<action no="2" type="abc"/>
<action no="3" type="ddd"/>
</input>
An XSD check should fail when
attribute no does not start at 1
the attributes are not ordered 1, 2, 3 ...
there are numbers missing like 1, 3, 4
Thats my current XSD
<complexType name="action">
<attribute name="no" use="required">
<simpleType>
<restriction base="int">
<minInclusive value="1"></minInclusive>
<maxInclusive value="99"></maxInclusive>
<whiteSpace value="collapse"></whiteSpace>
</restriction>
</simpleType>
</attribute>
<attribute name="type" type="string"></attribute>
</complexType>
<complexType name="input">
<sequence>
<element name="action" type="tns:action"></element>
</sequence>
</complexType>
In XSD 1.1 you could use an assertion:
<xs:element name="input">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="action"/>
</xs:sequence>
<xs:assert id="sequence-of-no-values" test="every $i in 1 to count(action) satisfies $i eq action[$i]/#no"/>
</xs:complexType>
</xs:element>
I've got the following schema declaration:
<element name="container">
<complexType>
<choice minOccurs="0" maxOccurs="unbounded">
<element name="action" minOccurs="0" maxOccurs="1" />
<element name="query" minOccurs="0" maxOccurs="unbounded" />
<element name="validator" minOccurs="0" maxOccurs="unbounded" />
</choice>
</complexType>
</element>
I basically want a <container> to include as many <query> or <validator> elements as wanted, but only one <action> element (and possibly none).
As far as I know I can't put a maxOccurs on the <choice> since technically that choice can be made an unlimited number of times (due to the unbouded on query and validator).
However, this XML is considered valid in Eclipse (which may just well be a problem in Eclipse validation, although all the other bits work fine)
<container>
<action id="action1" name="action1" />
<action id="action2" name="action2" />
<query id="query1" />
<validator id="testValidator" />
</container>
Not sure if I'm missing something obvious.
Your current model defines a choice among (a) one action element or none, (b) zero or more query elements, or (c) zero or more validator elements, and then allows that choice to be repeated zero or more times. It is thus equivalent to
<choice minOccurs="0" maxOccurs="unbounded">
<element name="action"/>
<element name="query"/>
<element name="validator"/>
</choice>
which allows any sequence of zero or more elements each of which is an action, a query, or a validator element.
The requirements you formulate can be met by using sequence instead of choice:
<sequence>
<element name="action" minOccurs="0" maxOccurs="1" />
<element name="query" minOccurs="0" maxOccurs="unbounded" />
<element name="validator" minOccurs="0" maxOccurs="unbounded" />
</sequence>
Sometimes the sequence in which the different kinds of elements occur conveys information, and it is therefore necessary to allow them to be intermingled. In that case, the problem is analogous to the following reqular-expression problem: write a regular expression defining the set of strings consisting of 'a', 'q', and 'v', in which 'a' occurs at most once. One obvious regex for this is (q|v)*(a(q|v)?). The analogous XSD model group is:
<sequence>
<choice minOccurs="0" maxOccurs="unbounded">
<element ref="query"/>
<element ref="validator"/>
</choice>
<sequence minOccurs="0">
<element name="action"/>
<choice minOccurs="0" maxOccurs="unbounded">
<element ref="query"/>
<element ref="validator"/>
</choice>
</sequence>
</sequence>
(I've changed from local element declarations to element references, to avoid having to declare query and validator twice each.)
In XSD 1.1, it should be possible to get the same effect with an all group:
<all>
<element name="action" minOccurs="0" maxOccurs="1" />
<element name="query" minOccurs="0" maxOccurs="unbounded" />
<element name="validator" minOccurs="0" maxOccurs="unbounded" />
</all>
I'm trying to represent the following DTD fragment in XSD:-
(A | B)* | (A | C)* | (A | D)* | ...
i.e. a mixed list of any number of As and any number of one of B, C, D, ...
CastorConverter spits out:-
<choice>
<choice minOccurs="0" maxOccurs="unbounded">
<element ref="tns:A" />
<element ref="tns:B" />
</choice>
<choice minOccurs="0" maxOccurs="unbounded">
<element ref="tns:A" />
<element ref="tns:C" />
</choice>
<choice minOccurs="0" maxOccurs="unbounded">
<element ref="tns:A" />
<element ref="tns:D" />
</choice>
</choice>
but this gives me a parser error. Investigating with visual studio brings up the following warning:-
"Multiple definition of element 'A' causes the content model to become ambiguous. A content model must be formed such that during validation of an element information item sequence, the particle contained directly, indirectly or implicitly therein with which to attempt to validate each item in the sequence in turn can be uniquely determined without examining the content or attributes of that item, and without any information about the items in the remainder of the sequence."
The problem appears to be that if the parser encounters an "A" will need to "look-ahead" to the rest of the sequence in order to determine which choice to validate against.
Is there another way I can represent this sequence in XSD?
Use sequences, like this:
<sequence minOccurs="0">
<element minOccurs="0" maxOccurs="unbounded" ref="tns:A" />
<choice>
<sequence>
<element minOccurs="1" maxOccurs="unbounded" ref="tns:B" />
<sequence minOccurs="0" maxOccurs="unbounded">
<element maxOccurs="unbounded" ref="tns:A" />
<element minOccurs="0" maxOccurs="unbounded" ref="tns:B" />
</sequence>
</sequence>
<sequence>
<element minOccurs="1" maxOccurs="unbounded" ref="tns:C" />
<sequence minOccurs="0" maxOccurs="unbounded">
<element maxOccurs="unbounded" ref="tns:A" />
<element minOccurs="0" maxOccurs="unbounded" ref="tns:C" />
</sequence>
</sequence>
<sequence>
<element minOccurs="1" maxOccurs="unbounded" ref="tns:D" />
<sequence minOccurs="0" maxOccurs="unbounded">
<element maxOccurs="unbounded" ref="tns:A" />
<element minOccurs="0" maxOccurs="unbounded" ref="tns:D" />
</sequence>
</sequence>
</choice>
</sequence>
alt text http://www.freeimagehosting.net/uploads/29c07bafa2.png
I'm trying to use SvcUtil against a wsdl file to generate proxy classes, but I'm getting an element missing error that I think is related to schema group elements. Does anyone know for a fact if svcutil can handle ? And if so will it handle xs:group elements that have ref attributes that point to the group definition that lives in another schema file?
SvcUtil.exe Command (included the paths to the xsd files as well):
d:\codegen\svcutil.exe d:\codegen\RPE\ProtocolStateManager.wsdl d:\codegen\RPE\schema\RPE.xsd d:\codegen\RPE\schema\PORT_MT100001UV.xsd d:\codegen\RPE\schema\coreschemas\infrastructureRoot.xsd d:\codegen\RPE\schema\coreschemas\dataTypes.xsd d:\codegen\RPE\schema\coreschemas\voc.xsd /l:cs
The error is:
Error: Cannot import wsdl:portType
Detail: An exception was thrown while
running a WSDL import extension:
System.ServiceModel.Description.XmlSerializerMessageContractImporter
Error: Group
InfrastructureRootElements is missing.
XPath to Error Source:
//wsdl:definitions[#targetNamespace='urn:ihe:qrph:rpe:2009']/wsdl:portType[#name= 'ProtocolStateManager']
ProtocolStateManager.wsdl:
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="ProtocolStateManager"
targetNamespace="urn:ihe:qrph:rpe:2009"
xmlns:rpe="urn:ihe:qrph:rpe:2009"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:plnk="http://schemas.xmlsoap.org/ws/2003/05/partner-link/">
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
TYPE DEFINITION - List of services participating in this BPEL process
The default output of the BPEL designer uses strings as input and
output to the BPEL Process. But you can define or import any XML
Schema type and use them as part of the message types.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<types>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:ihe:qrph:rpe:2009">
<include schemaLocation="schema\RPE.xsd"/>
</schema>
</types>
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
MESSAGE TYPE DEFINITION - Definition of the message types used as
part of the port type defintions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<message name="EnterPatientRequestRequestMessage">
<part name="payload" element="rpe:EnterPatientRequest"/>
</message>
<message name="EnterPatientRequestResponseMessage">
<part name="payload" element="rpe:EnterPatientRequest"/>
</message>
<message name="PatientScreeningVisitsScheduledRequestMessage">
<part name="payload" element="rpe:PatientScreeningVisitsScheduled"/>
</message>
<message name="PatientScreeningVisitsScheduledResponseMessage">
<part name="payload" element="rpe:PatientScreeningVisitsScheduled"/>
</message>
<message name="PatientScreeningVisitRecordedRequestMessage">
<part name="payload" element="rpe:PatientScreeningVisitRecorded"/>
</message>
<message name="PatientScreeningVisitRecordedResponseMessage">
<part name="payload" element="rpe:PatientScreeningVisitRecorded"/>
</message>
<message name="EnrollPatientRequestRequestMessage">
<part name="payload" element="rpe:EnrollPatientRequest"/>
</message>
<message name="EnrollPatientRequestResponseMessage">
<part name="payload" element="rpe:EnrollPatientRequest"/>
</message>
<message name="PatientStudyVisitsScheduledRequestMessage">
<part name="payload" element="rpe:PatientStudyVisitsScheduled"/>
</message>
<message name="PatientStudyVisitsScheduledResponseMessage">
<part name="payload" element="rpe:PatientStudyVisitsScheduled"/>
</message>
<message name="PatientStudyVisitRecordedRequestMessage">
<part name="payload" element="rpe:PatientStudyVisitRecorded"/>
</message>
<message name="PatientStudyVisitRecordedResponseMessage">
<part name="payload" element="rpe:PatientStudyVisitRecorded"/>
</message>
<message name="AlertProtocolStateMessage">
<part name="payload" element="rpe:AlertProtocolState"/>
</message>
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PORT TYPE DEFINITION - A port type groups a set of operations into
a logical service unit.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<!-- portType implemented by the ProtocolStateManager BPEL process -->
<portType name="ProtocolStateManager">
<operation name="EnterPatientRequest">
<input message="rpe:EnterPatientRequestRequestMessage"/>
<output message="rpe:EnterPatientRequestResponseMessage"/>
</operation>
<operation name="PatientScreeningVisitsScheduled">
<input message="rpe:PatientScreeningVisitsScheduledRequestMessage"/>
<output message="rpe:PatientScreeningVisitsScheduledResponseMessage"/>
</operation>
<operation name="RecordPatientScreeningVisit">
<input message="rpe:PatientScreeningVisitRecordedRequestMessage"/>
<output message="rpe:PatientScreeningVisitRecordedResponseMessage"/>
</operation>
<operation name="EnrollPatientRequest">
<input message="rpe:EnrollPatientRequestRequestMessage"/>
<output message="rpe:EnrollPatientRequestResponseMessage"/>
</operation>
<operation name="PatientStudyVisitsScheduled">
<input message="rpe:PatientStudyVisitsScheduledRequestMessage"/>
<output message="rpe:PatientStudyVisitsScheduledResponseMessage"/>
</operation>
<operation name="RecordPatientStudyVisit">
<input message="rpe:PatientStudyVisitRecordedRequestMessage"/>
<output message="rpe:PatientStudyVisitRecordedResponseMessage"/>
</operation>
</portType>
<portType name="ProtocolStateManagerCallback">
<operation name="onAlertProtocolState">
<input message="rpe:AlertProtocolStateMessage"/>
</operation>
</portType>
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PARTNER LINK TYPE DEFINITION
the ProtocolStateManager partnerLinkType binds the provider and
requester portType into an asynchronous conversation.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<plnk:partnerLinkType name="ProtocolStateManager">
<plnk:role name="ProtocolStateManagerProvider">
<plnk:portType name="rpe:ProtocolStateManager"/>
</plnk:role>
<plnk:role name="ProtocolStateManagerCallbackListener">
<plnk:portType name="rpe:ProtocolStateManagerCallback"/>
</plnk:role>
</plnk:partnerLinkType>
</definitions>
RPE.xsd (reference by ProtocolStateManager.wsdl):
<schema attributeFormDefault="unqualified" elementFormDefault="qualified"
targetNamespace="urn:ihe:qrph:rpe:2009"
xmlns:rpe="urn:ihe:qrph:rpe:2009"
xmlns:v3="urn:hl7-org:v3"
xmlns="http://www.w3.org/2001/XMLSchema">
<import namespace="urn:hl7-org:v3" schemaLocation="PORT_MT100001UV.xsd"/>
<element name="RetrieveProtocolDef" type="rpe:RetrieveProtocolDefType"/>
<element name="EnterPatientRequest" type="rpe:EnterPatientRequestType"/>
<element name="EnrollPatientRequest" type="rpe:EnrollPatientRequestType"/>
<element name="PatientScreeningVisitsScheduled" type="rpe:PatientScreeningVisitsScheduledType"/>
<element name="PatientScreeningVisitRecorded" type="rpe:PatientScreeningVisitRecordedType"/>
<element name="PatientStudyVisitsScheduled" type="rpe:PatientStudyVisitsScheduledType"/>
<element name="PatientStudyVisitRecorded" type="rpe:PatientStudyVisitRecordedType"/>
<element name="AmendProtocolDef" type="rpe:AmendProtocolDefType"/>
<element name="AlertProtocolState" type="rpe:AlertProtocolStateType"/>
<!-- need patient information and study information
EnterPatientRequestType can also be used for the return of candidateID?-->
<complexType name="RetrieveProtocolDefType">
<sequence>
<element name="query" type="string"/>
<element name="protocolDef" type="string"/>
</sequence>
</complexType>
<complexType name="EnterPatientRequestType">
<sequence>
<element name="patient" type="rpe:PatientType"/>
<element name="study" type="v3:PORT_MT100001UV.Study"/>
</sequence>
</complexType>
<!-- need patient for candidateID of the patient being scheduled for screening visits
need studyID to associate the candidate with the study
need schedule information-->
<complexType name="PatientScreeningVisitsScheduledType">
<sequence>
<element name="patient" type="rpe:PatientType"/>
<element name="studyID" type="v3:II"/>
<element name="schedule" type="rpe:ScreeningVisitScheduleType"/>
</sequence>
</complexType>
<!-- need patient for candidateID of patient being recorded for screening visit
need studyID to associate the candidate with the study
need visit information for the screening visit being recorded-->
<complexType name="PatientScreeningVisitRecordedType">
<sequence>
<element name="patient" type="rpe:PatientType"/>
<element name="studyID" type="v3:II"/>
<element name="visit" type="rpe:ScreenVisitType"/>
</sequence>
</complexType>
<!-- need patient information and study information
EnterPatientRequestType can also be used for the return of subjectID?-->
<complexType name="EnrollPatientRequestType">
<sequence>
<element name="patient" type="rpe:PatientType"/>
<element name="study" type="v3:PORT_MT100001UV.Study"/>
</sequence>
</complexType>
<!-- need patient for subjectID of the patient being scheduled for visits
need studyID to associate the subject with the study
need schedule information-->
<complexType name="PatientStudyVisitsScheduledType">
<sequence>
<element name="patient" type="rpe:PatientType"/>
<element name="studyID" type="v3:II"/>
<element name="schedule" type="rpe:StudyVisitScheduleType"/>
</sequence>
</complexType>
<!-- need patient for subjectID of patient being recorded for visit
need studyID to associate the subject with the study
need visit information for the visit being recorded-->
<complexType name="PatientStudyVisitRecordedType">
<sequence>
<element name="patient" type="rpe:PatientType"/>
<element name="studyID" type="v3:II"/>
<element name="visit" type="rpe:StudyVisitType"/>
</sequence>
</complexType>
<!-- patient information should NOT include emrID?
should contain placeholder for candidateID and subjectID
what specific demographics data is needed?
Should this be a generic type so that an XML standard can be passed?-->
<complexType name="PatientType">
<sequence>
<element name="candidateID" type="string"/>
<element name="subjectID" type="string"/>
<element name="name" type="string"/>
<element name="address" type="string"/>
<element name="dob" type="string"/>
</sequence>
</complexType>
<!-- studyID to identify the study
should studyData be a generic type to store an XML standard
<complexType name="StudyType">
<sequence>
<element name="studyID" type="string"/>
<element name="studyData" type="string"/>
</sequence>
</complexType>-->
<complexType name="ScreenVisitType">
<sequence>
<element name="visitID" type="string"/>
<element name="candidateID" type="string"/>
<element name="date" type="string"/>
<element name="screenVisitData" type="string"/>
</sequence>
</complexType>
<complexType name="StudyVisitType">
<sequence>
<element name="visitID" type="string"/>
<element name="subjectID" type="string"/>
<element name="date" type="string"/>
<element name="studyVisitData" type="string"/>
</sequence>
</complexType>
<complexType name="ScreeningVisitScheduleType">
<sequence>
<element name="visit" type="rpe:ScreenVisitType" maxOccurs="unbounded"/>
</sequence>
</complexType>
<complexType name="StudyVisitScheduleType">
<sequence>
<element name="visit" type="rpe:StudyVisitType" maxOccurs="unbounded"/>
</sequence>
</complexType>
<complexType name="AmendProtocolDefType">
<sequence>
<element name="protocolDef" type="string"/>
</sequence>
</complexType>
<complexType name="AlertProtocolStateType">
<sequence>
<element name="patient" type="rpe:PatientType"/>
<element name="study" type="v3:PORT_MT100001UV.Study"/>
</sequence>
</complexType>
</schema>
Snippet from PORT_MT100001UV.xsd (Referenced by RPE.xsd) - notice the "InfrastructureRootElements" xs:group:
<xs:complexType name="PORT_MT100001UV.Access">
<xs:sequence>
<xs:group ref="InfrastructureRootElements"/>
<xs:element name="id" type="II" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="targetSiteCode" type="CD" minOccurs="0" maxOccurs="1"/>
<xs:choice>
<xs:choice>
<xs:element name="accessedPerson" type="PORT_MT100001UV.Person" nillable="true"
minOccurs="0"
maxOccurs="1"/>
<xs:element name="accessedNonPersonLivingSubject"
type="PORT_MT100001UV.NonPersonLivingSubject"
nillable="true"
minOccurs="0"
maxOccurs="1"/>
</xs:choice>
<xs:element name="accessedProduct" type="PORT_MT100001UV.Product" nillable="true"
minOccurs="0"
maxOccurs="1"/>
</xs:choice>
</xs:sequence>
<xs:attributeGroup ref="InfrastructureRootAttributes"/>
<xs:attribute name="nullFlavor" type="NullFlavor" use="optional"/>
<xs:attribute name="classCode" type="RoleClassAccess" use="required"/>
</xs:complexType>
infrastructureRoot.xsd (reference by PORT_MT100001UV.xsd) notice the definition of the InfrastructureRootElements group here - this is the same group from the above schema that has the ref attribute:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema xmlns:mif="urn:hl7-org:v3/mif" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:v3="urn:hl7-org:v3"
xmlns:ex="urn:hl7-org/v3-example"
elementFormDefault="qualified">
<xs:annotation xmlns="urn:hl7-org:v3">
<xs:documentation>Source Information...</xs:documentation>
</xs:annotation>
<xs:include schemaLocation="voc.xsd"/>
<xs:include schemaLocation="datatypes.xsd"/>
<xs:group name="InfrastructureRootElements">
<xs:sequence>
<xs:element name="realmCode" type="CS" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="typeId" type="II" minOccurs="0" maxOccurs="1"/>
<xs:element name="templateId" type="II" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:group>
<xs:attributeGroup name="InfrastructureRootAttributes"/>
</xs:schema>
I found this tool - WSCF Blue - from a post on msdn forums. It got me past my errors and also looks to offer quite a bit more in terms of functionality.
I'm not sure about SvcUtil, but for XSD.exe and WSDL.exe you have to specify all the files that are used by the .xsd file, because they don't recognize elements. Maybe my post will help you, too: http://seanmcilvenna.com/blog/7-general/30-xca-implementation
I have a xml file like this:
<customer>
<field1 />
<field2 />
<field3>
<item1 />
</field3>
<field3>
<item1 />
</field3>
</customer>
field* can appear in any order and only field3 can appear more than once.
How can I create a XSD file to validate this?
Thank you!
Try this
I'm not a guru, but this appears to work.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="customer" type="customerType"/>
<xs:complexType name="customerType">
<xs:sequence>
<xs:element name="field1" minOccurs="1" maxOccurs="1">
</xs:element>
<xs:element name="field2" minOccurs="1" maxOccurs="1">
</xs:element>
<xs:element name="field3" type="field3Type"
minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="field3Type">
<xs:sequence>
<xs:element name="item1">
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>
tools
I used XML Copy Editor, but there are loads of editors which will validate XML.
links
You might also be interested in this article about generating an XSD from an XML file.
Hum, this is the kind of work xsd is really not handy for. Anyway, this should do the trick if I did not make a mistake:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/NewXMLSchema"
xmlns:tns="http://www.example.org/NewXMLSchema" elementFormDefault="qualified">
<element name="customer" type="tns:customerType"/>
<complexType name="customerType">
<sequence>
<element>
<complexType>
<all>
<element>
<complexType>
<sequence>
<element ref="tns:field3" maxOccurs="unbounded"/>
<element ref="tns:field1" maxOccurs="1"/>
</sequence>
</complexType>
</element>
<element>
<complexType>
<sequence>
<element ref="tns:field3" maxOccurs="unbounded"/>
<element ref="tns:field2" maxOccurs="1"/>
</sequence>
</complexType>
</element>
<element>
<complexType>
<sequence>
<element ref="tns:field3" maxOccurs="unbounded"/>
<element ref="tns:field4" maxOccurs="1"/>
</sequence>
</complexType>
</element>
</all>
</complexType>
</element>
<element ref="tns:field3" maxOccurs="unbounded" />
</sequence>
</complexType>
<complexType name="field1Container"/>
<complexType name="field2Container"/>
<complexType name="field3Type">
<sequence>
<element name="item1"/>
</sequence>
</complexType>
<complexType name="field4Container"/>
<element name="field3" type="tns:field3Type"/>
<element name="field1"/>
<element name="field2"/>
<element name="field4"/>
</schema>