I'm trying to extend an existing complextype in a XSD file.
I have created a new xsd file and included it at the end of all the master XSD files includes.
The problem I'm having is that it seems to add my extension but it removes the existing elements other than those defined in asset_abstract
Is what I'm trying to do possible?
Code I don't want to modify
<xs:complexType name="Feature_Cadastre_Lot" abstract="false">
<xs:annotation>
<xs:documentation>Represents the boundary of a titled, or proposed lot</xs:documentation>
</xs:annotation>
<xs:complexContent>
<xs:extension base="asset_abstract">
<xs:sequence minOccurs="1" maxOccurs="1">
<xs:element name="LotNo" type="String_32" minOccurs="1" maxOccurs="1" nillable="false">
<xs:annotation>
<xs:documentation>The lot number as described on the originating survey plan</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="PlanNo" type="String_32" minOccurs="1" maxOccurs="1" nillable="false">
<xs:annotation>
<xs:documentation>The plan number of the originating survey plan.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="CancelledLotPlan" type="String_32" minOccurs="1" maxOccurs="1" nillable="true">
<xs:annotation>
<xs:documentation>The lot on plan cancelled by this boundary if applicable.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="TitledArea_sqm" type="Float_Positive_NonZero" minOccurs="1" maxOccurs="1" nillable="false">
<xs:annotation>
<xs:documentation>The area in square metres enclosed by the boundary, as described by the survey plan.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="Geometry" type="geometry_area_multipatch_simple" minOccurs="1" maxOccurs="1" nillable="false">
<xs:annotation>
<xs:documentation>The geometry of this feature in coordinate space. May contain holes and islands. Boundaries must consist of straight lines.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
Code I can import to extend the scheme.
<xs:complexType name="Feature_Cadastre_Lot">
<xs:complexContent>
<xs:extension base="asset_abstract">
<xs:sequence>
<xs:element name="LMS_ID_1" type="String_32" minOccurs="1" maxOccurs="1" nillable="false">
<xs:annotation>
<xs:documentation>The Land Management System ID as defined by the LMS Team</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="LMS_ID_2" type="String_32" minOccurs="1" maxOccurs="1" nillable="false">
<xs:annotation>
<xs:documentation>The Land Management System ID as defined by the LMS Team</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
OK I've created a bare bones exmaple and I still can't get it to work now using visual studio as I wanna make sure its not the tool :) , I still can't get it too work as yours is :( I must be missing something.
Basically I've added 2 files Master.xsd and local.xsd
Master wraps the remote project I can't / don't want to modify direct and local.xsd is where all our site specific stuff (redefining as it is called).
Master.xsd
<?xml version="1.0"?>
<xs:schema version="1.0.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:include schemaLocation="project.xsd">
</xs:include>
<xs:include schemaLocation="local.xsd">
<xs:annotation>
<xs:documentation>A File I can add my overwrites to</xs:documentation>
</xs:annotation>
</xs:include>
</xs:schema>
project.xsd
<?xml version="1.0"?>
<xs:schema version="1.0.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:include schemaLocation="remote.xsd">
<xs:annotation>
<xs:documentation>A File that contains the complexType I want to add elments to. But not modify otherwise</xs:documentation>
</xs:annotation>
</xs:include>
<xs:element name="Master_Project">
<xs:annotation>
<xs:documentation>The Project.</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="ProjectData">
<xs:complexType>
<xs:sequence>
<xs:element name="ExistingElement" type="ExistingElementType">
<xs:annotation>
<xs:documentation>An Existing Element That I would Like To Add To.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
local.xsd
<?xml version="1.0"?>
<xs:schema version="1.0.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:redefine schemaLocation="./remote.xsd">
<xs:complexType name="ExistingElementType">
<xs:complexContent>
<xs:extension base="ExistingElementType">
<xs:sequence>
<xs:element name="newTest"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:redefine>
</xs:schema>
remote.xsd
<?xml version="1.0"?>
<xs:schema version="1.0.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:complexType name="ExistingElementType">
<xs:sequence>
<xs:element name="someProperty"/>
<xs:element name="someSecondProperty"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
And where I do all the redefining eventually.
If you want to keep the name of the complex type as "Feature_Cadastre_Lot" and extend it with additional content, then you are looking at redefine instead. The net effect is that all references to "Feature_Cadastre_Lot", preexisting and new, will include the newly added content.
If you want this in some, but not all of the existing content, there is no solution to it (redefine is all or nothing).
The redefine has the following layout:
<xs:redefine schemaLocation="must resolve to your XSD">
<xs:complexType name="Feature_Cadastre_Lot">
<xs:complexContent>
<xs:extension base="Feature_Cadastre_Lot">
<xs:sequence>
<xs:element name="LMS_ID_1" type="String_32" minOccurs="1" maxOccurs="1" nillable="false">
<xs:annotation>
<xs:documentation>The Land Management System ID as defined by the LMS Team</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="LMS_ID_2" type="String_32" minOccurs="1" maxOccurs="1" nillable="false">
<xs:annotation>
<xs:documentation>The Land Management System ID as defined by the LMS Team</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:redefine>
The result will look like this:
You can see the highlighted sequence as showing the added content.
In Visual Studio 2010, the content also shows ok:
Notice the second sequence at the bottom.
Related
We have an xml file that consists of one root element, a directly following element and after that 0 to 255 other elements of one specific type.
Currently, our XSD file looks like this:
<xs:element name="TIM">
...
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="POINT" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation xml:lang="en">
Point
</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element ref="VALUE" minOccurs="0" maxOccurs="255">
<xs:annotation>
<xs:documentation xml:lang="en">
Value
</xs:documentation>
</xs:annotation>
</xs:element>
</xs:choice>
...
</xs:element>
How would I have to change this to say "Element Point once at the top, afterwards only ElementValue"?
Sounds like you want a simple sequence xs:sequence i.e. <xs:sequence><xs:element ref="POINT">..</xs:element><xs:element ref="VALUE" minOccurs="0" maxOccurs="255">..</xs:element></xs:sequence>.
I have an XSD to validate an XML file. The structure is as follows:
<root>
<child>
<size>2</size>
<childElement>Element 1</childElement>
<childElement>Element 2</childElement>
</child>
</root>
The number of childElements is dependent on the size provided i.e. if size was set as 3, not more than 3 childElements can be added.
I have tried using xs:alternative but it does not seem to work:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="child" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="size" type="xs:integer" maxOccurs="1"/>
<xs:element name="childElement" type="xs:string" maxOccurs="1">
<xs:alternative test="#size>1" maxOccurs="#size"/>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Is there a way of using xs:alternative or another tag to achieve this, or is this outside the realm of possibility with XSD?
Design recommendation: If your XML design can still be changed, eliminate the size element and convey that information implicitly rather than explicitly. By eliminating the duplication of information, you'll not need to check that the duplication is consistent.
If your XML design cannot still be changed, or if you choose not to change it...
XSD 1.0
Not possible. Would have to be checked out-of-band wrt XSD.
XSD 1.1
Possible using xs:assert:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified"
elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
vc:minVersion="1.1">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="child">
<xs:complexType>
<xs:sequence>
<xs:element name="size" type="xs:integer"/>
<xs:element name="childElement" maxOccurs="unbounded"/>
</xs:sequence>
<xs:assert test="count(childElement) = size"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
I want to model a container that has a list of references by id in enterprise architect.
A xsd is generated from that model.
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Container" type="Container"/>
<xs:complexType name="Container">
<xs:sequence>
<xs:element name="Element" type="Element" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:element name="Element" type="Element"/>
<xs:complexType name="Element">
<xs:sequence>
<xs:element name="Identifier" type="xs:ID" minOccurs="1" maxOccurs="1"/>
<xs:element name="Name" type="xs:string" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
Is it possible to find settings so such that a list of Id is generated?
(Not a list of full instances like it is now)
Here are the settings of the aggregation:
The goal is to have a list of ID in the container generated from the association and have the possibility to generate java code from the xsd that has a list of element, not ID.
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Container" type="Container"/>
<xs:complexType name="Container">
<xs:sequence>
<xs:element name="ElementRef" type="xs:IDREF" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:element name="Element" type="Element"/>
<xs:complexType name="Element">
<xs:sequence>
<xs:element name="Identifier" type="xs:ID" minOccurs="1" maxOccurs="1"/>
<xs:element name="Name" type="xs:string" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
So, the XSD shall have a list of IDREF, so that the java code generated from that shall have either a list of Identifiers or even better a list of Element.
Edit: added example of target xsd.
We have a definition of Person element where we want different elements to be required depending on
what they are doing. For example, if they are adding a Person, then different elements are required
to be sent versus updating a Person. Below in the example, the Person type is currently duplicated, which
of course is wrong. Is there a good way of representing this in the xsd so we can reuse the Person type.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="Person">
<xs:annotation>
<xs:documentation>This is the definition when changing a person</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="PartyName" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="GenderCode" type="GenderCode_Type" minOccurs="0" maxOccurs="1"/>
<xs:element name="BirthDate" type="xs:date" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Person">
<xs:annotation>
<xs:documentation>This is the definition when adding a person</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="PartyName" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="GenderCode" type="GenderCode_Type" minOccurs="1" maxOccurs="1"/>
<xs:element name="BirthDate" type="xs:date" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
The simplest way to have two different types for Person elements is to use local declarations of Person in the two different contexts you have in mind. For example, you might say:
<xs:element name="Add">
<xs:complexType>
<xs:sequence>
<xs:element name="Person" type="AddPerson"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Update">
<xs:complexType>
<xs:sequence>
<xs:element name="Person" type="ChangePerson"/>
</xs:sequence>
</xs:complexType>
</xs:element>
This example assumes that you have redefined your two complex types as AddPerson and ChangePerson.
If additionally you want to have the two complex types be explicitly related, you can derive them both by restriction from a generic Person type.
<xs:complexType name="Person">
<xs:annotation>
<xs:documentation>This is the generic
definition for persons</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="PartyName" type="xs:string"
minOccurs="0" maxOccurs="1"/>
<xs:element name="GenderCode" type="GenderCode_Type"
minOccurs="0" maxOccurs="1"/>
<xs:element name="BirthDate" type="xs:date"
minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ChangePerson">
<xs:annotation>
<xs:documentation>This is the definition
when changing a person</xs:documentation>
</xs:annotation>
<xs:complexContent>
<xs:restriction base="Person">
<xs:sequence>
<xs:element name="PartyName" type="xs:string"
minOccurs="0" maxOccurs="1"/>
<xs:element name="GenderCode" type="GenderCode_Type"
minOccurs="0" maxOccurs="1"/>
<xs:element name="BirthDate" type="xs:date"
minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="AddPerson">
<xs:annotation>
<xs:documentation>This is the definition
when adding a person</xs:documentation>
</xs:annotation>
<xs:complexContent>
<xs:restriction base="Person">
<xs:sequence>
<xs:element name="PartyName" type="xs:string"
minOccurs="1" maxOccurs="1"/>
<xs:element name="GenderCode" type="GenderCode_Type"
minOccurs="1" maxOccurs="1"/>
<xs:element name="BirthDate" type="xs:date"
minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
Here, the generic type Person is identical to the AddPerson type; I've defined AddPerson using a vacuous restriction just for the symmetry of deriving both of the operation-specific types from the generic type.
Whether having such an explicit relation among your types actually helps you achieve your goals will depend, of course, in part on what use your system makes of your schema type definitions.
If you look at the following xsd fragment you can conclude that the corresponding xml will first contain cars followed by busses eg:
car,car,bus,bus
HOWEVER I want the xml to be able to contain
car,bus,car,bus
What change do I need to make in the xsd below in order to achieve this?
<xs:element name="body">
<xs:complexType>
<xs:sequence>
<xs:element name="session" type="tns:session" />
<xs:element minOccurs="0" maxOccurs="unbounded" name="car" type="tns:car" />
<xs:element minOccurs="0" maxOccurs="unbounded" name="bus" type="tns:bus" />
</xs:sequence>
</xs:complexType>
</xs:element>
It's a bit cumbersome, but you might achieve what you're looking for like this:
create a <xs:choice> element with your car and bus elements inside; this defines that one of the contained elements can be used
make sure to have the attribtues minOccurs=1 and maxOccurs=unbounded on that <xs:choice> - this gives you any number of either car or bus elements - any number, any combination
So your XML schema would look something like this (I added some stuff just to be able to generate a sample XML and verify it works - tweak as needed):
<?xml version="1.0" encoding="utf-8"?>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="body">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element minOccurs="0" maxOccurs="unbounded" name="car" type="CarType" />
<xs:element minOccurs="0" maxOccurs="unbounded" name="bus" type="BusType" />
</xs:choice>
</xs:complexType>
</xs:element>
<xs:complexType name="CarType">
<xs:sequence>
<xs:element name="Maker" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="BusType">
<xs:sequence>
<xs:element name="Maker" type="xs:string" />
<xs:element name="Capacity" type="xs:int" />
</xs:sequence>
</xs:complexType>
</xs:schema>
use <xs:any> insted of <xs:sequence>