For the following xml need a schema.
<?xml version="1.0" encoding="UTF-8"?>
<overall_operation>
<operation type="list_products">
<ops_description>Listing all the products of a company</ops_description>
<module>powesystem</module>
<comp_name>APC</comp_name>
<prod_price>50K$</prod_price>
<manf_date>2001</manf_date>
<pool_name>Electrical</pool_name>
<fail_retry>2</fail_retry>
<storage_type>avialble</storage_type>
<storage_check>false</storage_check>
<api_type>sync</api_type>
<product_name>transformer</product_name>
</operation>
<operation type="search_product">
<ops_description>Search the products of a company from the repository</ops_description>
<module>high-voltage</module>
<module>powesystem</module>
<comp_name>APC</comp_name>
<pool_name>Electrical</pool_name>
<fail_retry>2</fail_retry>
<storage_type>avialble</storage_type>
<storage_check>false</storage_check>
<api_type>sync</api_type>
<product_name>setup-transformer</product_name>
</operation>
</overall_operation>
Here different elements with operation like list_products,search_products and so on.
Each element will have some common attributes such as ops_description,module and so on.
Also some of the unique attributes for each element such as prod_price,manf_date etc.
I want to have a xml schema to validate. Some of the attributes also optional.
I tried using abstract and derived but could not make it work.
What you want to achieve is not possible with xml schema. The definition states that every element or attribute must be validated on its own and without reference to other elements or attributes.
The best solution you can get is to group optional but dependent elements:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="overall_operation">
<xs:complexType>
<xs:sequence>
<xs:element name="operation" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="ops_description" />
<xs:element name="module" minOccurs="1" maxOccurs="2" />
<xs:element name="comp_name" />
<xs:group ref="price_and_date" minOccurs="0" maxOccurs="1" />
<xs:element name="pool_name" />
<xs:element name="fail_retry" />
<xs:element name="storage_type" />
<xs:element name="storage_check" />
<xs:element name="api_type" />
<xs:element name="product_name" />
</xs:sequence>
<xs:attribute name="type" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:group name="price_and_date">
<xs:sequence>
<xs:element name="prod_price" />
<xs:element name="manf_date" />
</xs:sequence>
</xs:group>
</xs:schema>
Use minOccurs and maxOccurs attributes to control optional elements and groups.
Related
This is my sample XML code:
<Address>
<StreetAddress></StreetAddress>
<OtherDestination />
<City>TORONTO</City>
</Address>
That is currently using this XSD:
<xs:element name="Address" nillable="true">
<xs:complexType>
<xs:sequence minOccurs="0">
<xs:element ref="StreetAddress" minOccurs="0"/>
<xs:element ref="OtherDestination" minOccurs="0"/>
<xs:element ref="City" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
I want to add an attribute id to Address element like this..
<Address id="first">
<StreetAddress></StreetAddress>
<OtherDestination />
<City>TORONTO</City>
</Address>
How should I change the existing XSD to fulfill my requirement?
An attribute declaration can be added within xs:complexType after the xs:sequence:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:element name="Address">
<xs:complexType>
<xs:sequence>
<xs:element name="StreetAddress" minOccurs="0" type="xs:string"/>
<xs:element name="OtherDestination" minOccurs="0" type="xs:string"/>
<xs:element name="City" minOccurs="0" type="xs:string"/>
</xs:sequence>
<!------------------------------------------>
<!-- This is where to declare attributes: -->
<xs:attribute name="id" type="xs:string"/>
<!------------------------------------------>
</xs:complexType>
</xs:element>
</xs:schema>
The above XSD will validate your XML successfully.
My system parses two XML files (via JAXB unmarshalling and xjc generated code)
componentModel.xml : generated from a modeling tool
detailedDesign.xml : manual, to add informations
In order to avoid to code checks upon content and structures, each file is validated with its own XSD
componentModel.xsd
detailedDesign.xsd
Both of these xsd inclulde "utilities.xsd" where common complex and simple types are defined
All works well
I now want to add consistency check :
unicity of Ids (names of components)
components in "detailsDesign" must refers one of the components in "componentModel" via the "name" and "nameRef" attributes
Here are the structures (i've simlplified names and structures in files to show only relevant informations)
Note : as you can see, i don't use any namespace except the default one
componentModel.xml
<?xml version="1.0" encoding="UTF-8"?>
<componentModel>
<components>
<component name="id1"> ... </component>
<component name="id1"> ... </component>
<component name="id2"> ... </component>
</components>
</componentModel>
componentModel.xsd
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" >
<xs:include schemaLocation="utilities.xsd" />
<xs:complexType name="CMComponent">
<xs:complexContent>
...
<xs:attribute name="name" type="MUUpperFirstName" use="required" />
</xs:complexContent>
</xs:complexType>
<xs:complexType name="CMComponents">
<xs:sequence>
<xs:element name="component" type="CMComponent" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="CMComponentModel">
<xs:complexContent>
<xs:sequence>
<xs:element name="components" type="CMComponents">
<!-- Key used to check "name" unicity and as a ref by nameRef attribute in detailedDesign model -->
<xs:key name="componentNameKey">
<xs:selector xpath="component" />
<xs:field xpath="#name" />
</xs:key>
</xs:element>
<xs:element name="functionalChains" minOccurs="0" maxOccurs="1" />
</xs:sequence>
<xs:attribute name="name" type="MUModelName" use="required" />
</xs:complexContent>
</xs:complexType>
<xs:element name="componentModel" type="CMComponentModel" />
</xs:schema>
utilities.xsd
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="MUString">
<xs:restriction base="xs:string"/>
</xs:simpleType>
<xs:simpleType name="MUUpperFirstName">
<xs:restriction base="MUString">
<xs:pattern value="([A-Z]+[a-zA-Z0-9]*[.])*[A-Z]+[a-zA-Z0-9]*"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="MUReferenceName">
<xs:restriction base="MUString">
<xs:pattern value="([A-Z]+[a-zA-Z0-9]*[.])*[a-zA-Z]+[a-zA-Z0-9]*"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
detailedDesign.xml
<?xml version="1.0" encoding="UTF-8"?>
<detailedDesignModel>
<components>
<component nameRef="id1"> ... </component>
<component nameRef="id2"> ... </component>
<component nameRef="id3"> ... </component>
</components>
</detailedDesignModel>
detailedDesign.xsd
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:include schemaLocation="utilities.xsd" />
<xs:include schemaLocation="componentModel.xsd" />
<xs:complexType name="DDMComponent">
<xs:complexContent>
...
<xs:attribute name="nameRef" type="MUReferenceName" use="required" />
</xs:complexContent>
</xs:complexType>
<xs:complexType name="DDMComponents">
<xs:sequence>
<xs:element name="component" type="DDMComponent" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="DDMDetailDesignModel">
<xs:complexContent>
<xs:sequence>
<xs:element name="components" type="DDMComponents">
<xs:keyref name="componentNameKeyRef" refer="componentNameKey">
<xs:selector xpath="component" />
<xs:field xpath="#nameRef" />
</xs:keyref>
</xs:element>
</xs:sequence>
</xs:complexContent>
</xs:complexType>
<xs:element name="detailDesignModel" type="DDMDetailDesignModel" />
</xs:schema>
It works for unicity of 'name' attribute among components (error retrieved from ValidationEventHandler set on unmarshaller) :
Duplicate key value [id1] declared for identity constraint of element "components".
But i can't get the "keyref" functionnality working (error retrieved from ValidationEventHandler set on unmarshaller) :
Identity Constraint error: identity constraint "KeyRef#272ed83b" has a keyref which refers to a key or unique that is out of scope.
How can i make the keyRef to see the Key defined in the orther XSD file
Thanks
Matth
I have just made my first attempt at XSD.
When I try and validate my XML against my XSD, I get the error:
Cannot find the declaration of element 'linkage'.
Below I give my XSD and a cut down version of my XML. I've tried adding a namespace qualifier to the top element in my XML and also to every element (changing the XSD to qualified) and it did not help. I'm obviously making a basic mistake. As I'm new to XSD, if you could include what I need to change in my XML and/or XSD I would be very grateful.
XSD:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.stephenwaring.me.uk/android/nestedsettings"
xmlns="http://www.stephenwaring.me.uk/android/nestedsettings"
elementFormDefault="unqualified">
<xs:element name="linkage">
<xs:complexType>
<xs:sequence>
<xs:element name="preference-screen" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="parent" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="child" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="key" type="xs:token" use="required" />
<xs:attribute name="reformat" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attributeGroup ref="keyed" />
<xs:attribute name="preference-screen" type="xs:token" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attributeGroup ref="keyed"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attributeGroup ref="defaults"/>
</xs:complexType>
</xs:element>
<xs:attributeGroup name="defaults">
<xs:attribute name="html" type="xs:boolean" />
<xs:attribute name="prefix" type="xs:string" />
<xs:attribute name="suffix" type="xs:string" />
<xs:attribute name="separator" type="xs:string"/>
<xs:attribute name="reformat" type="xs:boolean" />
<xs:attribute name="shaddow" type="xs:boolean" />
<xs:attribute name="child-summary" type="xs:boolean" />
<xs:attribute name="shadow-separator" type="xs:string"/>
</xs:attributeGroup>
<xs:attributeGroup name="keyed">
<xs:attributeGroup ref="defaults" />
<xs:attribute name="key" type="xs:token" use="required" />
</xs:attributeGroup>
</xs:schema>
Cut down XML:
<?xml version="1.0" encoding="UTF-8"?>
<linkage
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://stevewaring.me.uk/android/nestedsettings nestedsettings.xsd"
xmlns="http://www.stevewaring.me.uk">
<preference-screen
key="preferences1">
<parent
key="prefFruit"
preference-screen="preferences2">
<child key="prefFruit1"/>
<child key="prefFruit2"/>
</parent>
</preference-screen>
</linkage>
Your XSD defines elements in http://www.stephenwaring.me.uk/android/nestedsettings whereas your document element is in http://www.stevewaring.me.uk. Make them to agree, one way or the other, and it should take care of the error you're having.
I've added a fixed XML, there's another issue related to use of unqualified elements.
<?xml version="1.0" encoding="UTF-8"?>
<linkage xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.stephenwaring.me.uk/android/nestedsettings nestedsettings.xsd" xmlns="http://www.stephenwaring.me.uk/android/nestedsettings">
<preference-screen xmlns="" key="preferences1">
<parent key="prefFruit" preference-screen="preferences2">
<child key="prefFruit1"/>
<child key="prefFruit2"/>
</parent>
</preference-screen>
</linkage>
I have been trying to form this XSD, can someone help please...
I have an element 'country' as below:
<xs:element name="country">
<xs:complexType>
<xs:sequence>
<xs:element name="id" type="xs:long" minOccurs="0" />
<xs:element name="isoCode" type="xs:string" minOccurs="0" />
<xs:element name="currencyCode" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
Now, I need to form XSD with two elements, 'source country' and 'destination country' which should both reference to 'country'. Can someone please help me to form that XSD.
<xs:element name="crossCountries">
<xs:complexType>
<xs:sequence>
<xs:element name="id" type="xs:long" minOccurs="0" />
<xs:element ref="country" /> <!-- Source Country -->
<xs:element ref="country" /> <!-- Destination Country -->
</xs:sequence>
</xs:complexType>
</xs:element>
You cannot reference an element and assign a different tag name to that reference. What you want to do instead is to define the content model for that element (a complex type would do) and reuse that under differently named tags.
<xs:complexType name="country">
<xs:sequence>
<xs:element name="id" type="xs:long" minOccurs="0" />
<xs:element name="isoCode" type="xs:string" minOccurs="0" />
<xs:element name="currencyCode" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
Then:
<xs:element name="crossCountries">
<xs:complexType>
<xs:sequence>
<xs:element name="id" type="xs:long" minOccurs="0" />
<xs:element name="sourceCountry" type="country" /> <!-- Source Country -->
<xs:element name="destinationCountry" type="country" /> <!-- Destination Country -->
</xs:sequence>
</xs:complexType>
</xs:element>
I want to express unordered mandatory and optional tags occurring reccurringly in an XSD.
Can any one tell how this problem can be resolved ?
If it is not feasible, what is the approach that can be taken.
UPDATE
<xs:element name="Tag1" type="xs:string" />
<xs:element name="Tag2" type="xs:string" />
<xs:element name="Tag3" type="xs:string" maxoccurs="Unbounded"/>
All these tags appear under a complext type and tag1 and tag2 are mandatory. tag3 is optional and can occur any number of times. tag1, tag2 and tag3 can appear in any order
You can use a "all" group selector and use minOccurs to indicate mandatory-ness.
<xs:schema xmlns="http://Message1" targetNamespace="http://Message1" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Root">
<xs:complexType>
<xs:all>
<xs:element name="TheValue" type="xs:string" />
<xs:element name="TheValue2" type="xs:string" minOccurs="0" />
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>
This are correct:
<ns0:Root xmlns:ns0="http://BizTalk_Server_Project1.Message1">
<TheValue2>somevalue</TheValue2>
<TheValue>somevalue</TheValue>
</ns0:Root>
and so it this:
<ns0:Root xmlns:ns0="http://BizTalk_Server_Project1.Message1">
<!--<TheValue2>somevalue</TheValue2>-->
<TheValue>somevalue</TheValue>
</ns0:Root>
But not this:
<ns0:Root xmlns:ns0="http://BizTalk_Server_Project1.Message1">
<!--<TheValue2>somevalue</TheValue2>-->
<!--<TheValue>somevalue</TheValue>-->
</ns0:Root>