I am trying to write a XML Schema which will validate a XML document like below. For validation purpose i am using xs:unique. I am trying to convert a tree into XML. So from the root there will be many branch. From root to leaf in one path entity name must be unique. An example path:
name0>scenarioDec>Entities>entityMultiAsp>Entity2>entitySpec>Entity2
in this path Entity2 added two times. So its not ok. I can't fix this problem.
Another path:
name0>scenarioDec>Events>eventMultiAsp>Aircraft>entitySpec>Entity2
Here Entity2 is ok. Because in this path no Entiy2 is added before.
I have tried using
<xs:selector xpath=".//entity"/>
instead of
<xs:selector xpath="*/entity"/>.
If i use .// then it is checking for all paths. But i need only one path uniqueness.
How can i solve this problem?
<?xml version="1.0" encoding="UTF-8"?>
<entity xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="file:/M:/axm.xsd"
name="name0">
<aspect name="scenarioDec">
<entity name="Environment">
<!-- for test -->
</entity>
<entity name="Entities"> <!-- -->
<multiAspect name="entityMultiAsp">
<entity name="Entity2">
<specialization name="entitySpec">
<entity name="Aircraft"/>
<entity name="Entity2"> <!-- it is not ok because in this path already one Entity2 added before.
name0>scenarioDec>Entities>entityMultiAsp>Entity2>entitySpec>Entity2-->
<var name="var1"></var>
<var name="var2"></var>
</entity>
</specialization>
</entity>
</multiAspect>
</entity>
<entity name="Events">
<multiAspect name="eventMultiAsp">
<entity name="Aircraft"> <!-- it is ok -->
<specialization name="entitySpec">
<entity name="Entity2"> <!-- it is ok because in this path no Entity2 is added before
name0>scenarioDec>Events>eventMultiAsp>Aircraft>entitySpec>Entity2-->
<var name="var1"></var>
<var name="var2"></var>
</entity>
</specialization>
</entity>
</multiAspect>
</entity>
</aspect>
</entity>
The XML schema for the above XML is given below:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1">
<xs:complexType name="aspectType">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="entity"/>
</xs:sequence>
<xs:attribute name="name" use="required"/>
</xs:complexType>
<xs:complexType name="multiAspectType">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="entity"/>
</xs:sequence>
<xs:attribute name="name" use="required"/>
</xs:complexType>
<xs:complexType name="specializationType">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="entity"/>
</xs:sequence>
<xs:attribute name="name" use="required"/>
</xs:complexType>
<xs:complexType name="varType"> <!-- mixed="true" -->
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="entity"/>
</xs:sequence>
<xs:attribute name="name" use="required"/>
</xs:complexType>
<xs:element name="entity">
<xs:complexType>
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="aspect"/>
<xs:element ref="specialization"/>
<xs:element ref="multiAspect"/>
<xs:element ref="var"/>
</xs:choice>
</xs:sequence>
<xs:attribute name="name" use="required"/>
<xs:assert test="every $x in .//* satisfies empty($x//*[node-name(.) = node-name($x)])"/>
</xs:complexType>
</xs:element>
<xs:element name="aspect" type="aspectType"/>
<xs:element name="multiAspect" type="multiAspectType"/>
<xs:element name="specialization" type="specializationType"/>
<xs:element name="var" type="varType"/>
</xs:schema>
Here i have added a picture to make the concept clear.
........ Edit 2: ........
<xs:element name="entity">
<xs:complexType>
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="aspect"/>
<xs:element ref="specialization"/>
<xs:element ref="multiAspect"/>
<xs:element ref="var"/>
</xs:choice>
</xs:sequence>
<xs:attribute name="name" use="required"/>
<xs:assert test="empty(../@name)"/>
<!--
Your suggestion:
<xs:assert test="empty(../Entity2)"/>
but for my case may be it will be
<xs:assert test="empty(../@name)"/>
as entity name is not fixed. I have tried both the way but it is not working.
-->
</xs:complexType>
-----Edit 3-------
I have four types of node: 1. Entity, 2. MultiAspect, 3. Aspect and 4. Specialization. If the node is Entity then its successors are Aspect, MultiAspect or Specialization. If the type of a node is Aspect, MultiAspect or Specialization, then the type of its children are Entity. The root node is always Entity.
I have designed my XML Schema using the above rules. I have used "assert" to validate the XML file. I have used
every $x in .//* satisfies empty($x//*[node-name(.) = node-name($x)])
and also tried using entity instead of *
every $x in .//entity satisfies empty($x//entity[node-name(.) = node- name($x)])
But it is showing error all the time. XML Schema is given above.
<?xml version="1.0" encoding="UTF-8"?>
<entity xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="file:/M:/axm.xsd" name="name0">
<aspect name="scenarioDec">
<entity name="Environment">
<multiAspect name="entityMAsp">
<!-- <entity name="EntityTest"></entity> --> <!-- if i add "EntityTest"
as an entity then it shows error but it should be correct -->
</multiAspect>
</entity>
</aspect>
</entity>
Inside "multiAspect" when I tried to add the below line it shows error.
<entity name="EntityTest">
But it should be correct.