问题
I have a schema as shown below ,i have a few questions regarding the schema
1.How to make CourierNumber
or WorkLocationCoordinate
mandatory.I have used one global type shown below
EDIT Still no luck as Abel mentioned i modifed schema but it is failing.The input xml is
<?xml version="1.0" encoding="utf-8"?>
<NOCPlantMapRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<NOCTypeID>0</NOCTypeID>
<WorkLocation>
<ParcelNumber>4545</ParcelNumber>
<Roads>
<WorkLocationRoad>
<RoadName>dubai road</RoadName>
</WorkLocationRoad>
</Roads>
<WorkArea>
<WorkArea>
<Coordinates>
<WorkLocationCoordinate>
<CoordinateX>56</CoordinateX>
<CoordinateY>23</CoordinateY>
</WorkLocationCoordinate>
</Coordinates>
<Communities />
</WorkArea>
</WorkArea>
</WorkLocation>
</NOCPlantMapRequest>
And the schema is
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
attributeFormDefault="unqualified"
elementFormDefault="qualified">
<xsd:element name="NOCPlantMapRequest">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="NOCReference" minOccurs="0" type="xsd:string" />
<xsd:element name="NOCTypeID" minOccurs="0" type="xsd:unsignedByte" />
<xsd:element name="NOCTypeName" minOccurs="0" type="xsd:string" />
<xsd:element name="ApplicationName" minOccurs="0" type="xsd:string" />
<xsd:element name="Applicationtype" minOccurs="0" type="xsd:string" />
<xsd:element name="RelatedNOCRefNumber" minOccurs="0" type="xsd:string" />
<xsd:element name="WorkLocation" minOccurs="1" maxOccurs="1" type="LocationType">
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="LocationType">
<xsd:choice>
<xsd:sequence>
<xsd:element name="ParcelNumber" type="ParcelNumberType" />
</xsd:sequence>
<xsd:sequence>
<xsd:element name="WorkArea" type="WorkAreaType" />
</xsd:sequence>
</xsd:choice>
</xsd:complexType>
<xsd:simpleType name="ParcelNumberType">
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
<xsd:complexType name="WorkAreaType">
<xsd:sequence>
<xsd:element name="WorkArea" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Coordinates" minOccurs="1" type="CoordinatesType" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CoordinatesType">
<xsd:sequence>
<xsd:element name="WorkLocationCoordinate" type="WorkLocationCoordinateType"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="WorkLocationCoordinateType">
<xsd:sequence>
<xsd:element name="CoordinateX" type="xsd:string" />
<xsd:element name="CoordinateY" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
But i am getting error as shown below Not valid.
Error - Line 6, 12: org.xml.sax.SAXParseException; lineNumber: 6; columnNumber: 12; cvc-complex-type.2.4.d: Invalid content was found starting with element 'Roads'. No child element is expected at this point.
Error - Line 19, 24: org.xml.sax.SAXParseException; lineNumber: 19; columnNumber: 24; cvc-complex-type.2.4.d: Invalid content was found starting with element 'Communities'. No child element is expected at this point.
My main requirement is either ParcelNumber
or WorkLocationCoordinateType
should present,what went wrong?
回答1:
1.How to make CourierNumber or WorkLocationCoordinate mandatory.I have used one global type shown below
In your given code, these two definitions are not close together (one is at the 2nd child level, the other is deeply nested) so I have some trouble understanding what you mean by this.
It is not possible to have two elements at the same level (same XPath) with the same name but different types. If you try it, you would get (depending on your XSD parser):
E [Xerces] cos-element-consistent: Error for type 'LocationType'.
Multiple elements with name 'WorkArea', with different types, appear in the model group.
If you can use XSD 1.1, you can work around this by using assertions. Since the only information in WorkArea
is the coordinates, I assume you mean to switch between either CourierNumber
in first position, or WorkArea
in second position, but not both (really, it would have helped to show an instance document with the variants you want).
If so how to apply the type in element name CourierNumber and WorkLocationCoordinate since 'CourierNumber' already contains type xsd:unsignedShort
This is where your real issue lies. Since you do not use named types (everything is one big element with anonymous complex type definitions), you cannot reference those types. One solution is to repeat the definitions, but this can become tedious and has its limitations.
The solution I provide you below simply refactors your code into a "type first" approach. That is, instead of one big (hard to read) element definition, you get small chunks of named type definitions. Opinions may vary, but I believe this is more readable, and it's definitely more flexible. A good introduction of this approach and what its drawbacks and features are can be found on XFront.
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
attributeFormDefault="unqualified"
elementFormDefault="qualified">
<!-- belonging to SO question https://stackoverflow.com/questions/33183835/how-to-make-either-of-the-fields-mandatory-in-xml-schema -->
<xsd:complexType name="CoordinatesType">
<xsd:sequence>
<xsd:element name="WorkLocationCoordinate" type="WorkLocationCoordinateType"/>
</xsd:sequence>
</xsd:complexType>
<xsd:simpleType name="CourierNumberType">
<xsd:restriction base="xsd:unsignedShort"/>
</xsd:simpleType>
<xsd:complexType name="WorkLocationCoordinateType">
<xsd:sequence>
<xsd:element name="CoordinateX" type="xsd:unsignedByte" />
<xsd:element name="CoordinateY" type="xsd:unsignedByte" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="WorkAreaType">
<xsd:sequence>
<xsd:element name="WorkArea">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Coordinates" type="CoordinatesType" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="LocationType">
<xsd:choice>
<xsd:sequence>
<xsd:element name="CourierNumber" type="CourierNumberType" />
<xsd:element name="Roads" />
</xsd:sequence>
<xsd:sequence>
<xsd:element name="Roads" />
<xsd:element name="WorkArea" type="WorkAreaType" />
</xsd:sequence>
</xsd:choice>
</xsd:complexType>
<xsd:element name="Request">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Location" type="LocationType" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
This validates either this:
<Request>
<Location>
<CourierNumber>12</CourierNumber>
<Roads></Roads>
</Location>
</Request>
Or this:
<Request>
<Location>
<Roads></Roads>
<WorkArea>
<WorkArea>
<Coordinates>
<WorkLocationCoordinate>
<CoordinateX>34</CoordinateX>
<CoordinateY>66</CoordinateY>
</WorkLocationCoordinate>
</Coordinates>
</WorkArea>
</WorkArea>
</Location>
</Request>
回答2:
You need to modify the definition of the "CourierNumber" element to include the required attribute. Update this code:
<xsd:element name="CourierNumber" type="xs:string"/>
to this:
<xsd:element name="CourierNumber">
<xsd:complexType>
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="Option" type="xsd:string" use="required"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
</xsd:element>
Reference from Element-Mandatory Attribute declaration in XSD Schema
<xsd:element name="Coordinates">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="WorkLocationCoordinate"
type="Test" minOccurs="1" maxOccurs="99"
/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="Test">
<xsd:sequence>
<xsd:element name="CoordinateX" type="xsd:unsignedByte" />
<xsd:element name="CoordinateY" type="xsd:unsignedByte" />
</xsd:sequence>
</xs:complexType>
If you define the type of your element inline you can't name it so remove the type="WorkLocationCoordinate"
attribute (and then the name="WorkLocationCoordinate"
attribute as well).
If you want to use those attributes then you need to separate element and type definition e.g. <xsl:element name="WorkLocationCoordinate" type="WorkLocationCoordinate"/>
and <xsl:complexType name="WorkLocationCoordinate">...</xsl:complexType>
.
For more information on the error you mention in the comments, see the type attribute cannot be present with either simpleType or complexType
来源:https://stackoverflow.com/questions/33183835/how-to-make-either-of-the-fields-mandatory-in-xml-schema