Element reference in 2 elements - xsd

I don't know how to title my question.
I have an XSD which contains the following elements
<xs:element name="abc">
<xs:complexType>
<xs:element maxOccurs="unbounded" ref="ele1"/>
</xs:complexType>
</xs:element>
<xs:element name="xyz">
<xs:complexType>
<xs:element maxOccurs="unbounded" ref="ele1"/>
</xs:complexType>
</xs:element>
<xs:element name="ele1">
<xs:complexType>
<xs:attribute name="ID" type="xs:integer"/>
</xs:complexType>
</xs:element>
The question is for element xyz ID is mandatory whereas for abc it is not; how can I specify this in the XSD?

Assuming ID is a unique identifier for the content repeated under the "container", then you could set a xs:key constraint for the xyz like this:
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="abc">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="ele1"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="xyz">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="ele1"/>
</xs:sequence>
</xs:complexType>
<xs:key name="PK_xyz">
<xs:selector xpath="ele1"/>
<xs:field xpath="#ID"/>
</xs:key>
</xs:element>
<xs:element name="ele1">
<xs:complexType>
<xs:attribute name="ID" type="xs:integer"/>
</xs:complexType>
</xs:element>
</xs:schema>
Then, invalid XML because ID is missing:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
<xyz xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ele1 ID="1"/>
<ele1 />
</xyz>
Error message:
Error occurred while loading [], line 5 position 3
The identity constraint 'PK_xyz' validation has failed. Either a key is missing or the existing key has an empty node.
Document3.xml is invalid.
Invalid because it is duplicate (this is the downside, if the above assumption on uniqueness doesn't stand true):
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
<xyz xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ele1 ID="1"/>
<ele1 ID="1"/>
</xyz>
Error:
Error occurred while loading [], line 5 position 3
There is a duplicate key sequence '1' for the 'PK_xyz' key or unique identity constraint.
Document3.xml is invalid.
Working sample:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
<xyz xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ele1 ID="1"/>
<ele1 ID="2"/>
</xyz>

Related

XSD, attributes for sequence elements [duplicate]

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.

Using keyRef in XSD : How to refer a key located in a different XSD (out of scope error)

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

XSD and xmllint : replacing xs:sequence with xs:all gives an error

I want to validate the following XML, without imposing the order of points :
<?xml version='1.0' encoding='ISO-8859-1'?>
<root>
<name>Map corners</name>
<point>NW</point>
<point>SW</point>
<point>NE</point>
<point>SE</point>
</root>
My XSD is :
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="point" type="xs:string" fixed="NW"/>
<xs:element name="point" type="xs:string" fixed="SW"/>
<xs:element name="point" type="xs:string" fixed="NE"/>
<xs:element name="point" type="xs:string" fixed="SE"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
xmllint validates my XML.
But if I replace xs:sequence with xs:all (to release the order constraint : SW may be before NW), it doesn't validate, and I have the following message :
my6.xsd:4: element complexType: Schemas parser error : local complex type: The content model is not determinist.
Did I miss something ?
In XSD 1.0, you can't use xsd:any with a repeating element particle. You can do something like this:
<?xml version="1.0" encoding="utf-8" ?>
<!-- XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com) -->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="point" minOccurs="4" maxOccurs="4">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="NW"/>
<xs:enumeration value="SW"/>
<xs:enumeration value="NE"/>
<xs:enumeration value="SE"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:key name="pk_points">
<xs:selector xpath="point"/>
<xs:field xpath="."/>
</xs:key>
</xs:element>
</xs:schema>

XSD validation restriction of maxoccurs

Hi I have this kind of XML
I would like to write an XML that validates this data:
<?xml version="1.0" encoding="UTF-8"?>
<Entry attribute1="value1" attribute2="Value2">
<subEntry tagX="xValue1" tagy="yValue"/>
</Entry>
but doesn't validate
<?xml version="1.0" encoding="UTF-8"?>
<Entry attribute1="value1" attribute2="Value2">
<subEntry tagX="xValue1" tagy="yValue"/>
<subEntry tagX="xValue1" tagy="yValue"/>
</Entry>
I would like to restrict the number of subEntries:
The maxOccurs of sequence don't check the number of subEntries.
The XSD is :
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="Entry">
<xs:complexType>
<xs:sequence>
<xs:element ref="subEntry"/>
</xs:sequence>
<xs:attribute1 name="dateEmission" type="xs:dateTime" use="required"/>
<xs:attribute2 name="emetteur" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="Entry">
<xs:complexType>
<xs:attribute name="tagX" type="xs:string" use="required"/>
<xs:attribute name="tagy" type="xs:decimal" use="optional"/>
</xs:complexType>
</xs:element>
</xs:schema>
You need to add maxOccurs on the element declaration. Change it to below
<xs:sequence>
<xs:element ref="subEntry" maxOccurs="1" />
</xs:sequence>

xml with same element with different value need a schema

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.

Resources