0

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.

enter image description here

........ 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.

2
  • I'm sorry, I don't understand the question. I have problems both in understanding your path notation (a>b>c) and in understanding your English (for example "Because in this path no Entiy2 is added before"). It would help to give examples of valid and invalid XML. Commented Oct 28, 2017 at 19:27
  • Dear Michael Kay, Sorry for my bad English. Now i have added a picture so that you can understand my question. Commented Oct 28, 2017 at 22:51

1 Answer 1

1

Thanks for your additional explanation, I think I now understand what you are trying to achieve.

I don't think this constraint can be expressed in XSD 1.0. In XSD 1.1 it can be done with an assertion:

<xs:element name="Entity2">
 ...
 <xsl:assert test="empty(.//Entity2)"/>
</xs:element>
7
  • Dear Michael, I tried using your suggestion but it is not working. May be I am not adding in the proper place where it should be added. Entity2 is not my fixed name. It's can be any name but it should be unique in any path from root to leaf of a tree according to that image. Sorry, May be still i couldn't make you understand what actually I am trying to do. I am really sorry for that. If you check my Edit 2 then may be you will understand. thank you. Commented Oct 29, 2017 at 15:41
  • 1
    Well, you could put an assertion in the declaration of the root element that no element in the document may have a same-name descendant: that would be test="every $x in .//* satisfies empty($x//*[node-name(.) = node-name($x)])". Commented Oct 29, 2017 at 18:19
  • Dear Michael Kay, From last few days I am trying using your suggestion. I am also reading your book. But unfortunately, i couldn't solve that problem yet. I have added Edit 3 section. Please look at that section. I am really trying my best. I am requesting you to check that again. Please give me some suggestion so that I can complete this task. Commented Nov 4, 2017 at 18:25
  • You seem to have a document with "entity" as its root, and with another "entity" as a descendant. And you have an assertion that says no element may have a descendant with the same name. Your instance document clearly doesn't satisfy that assertion. Commented Nov 4, 2017 at 19:07
  • 1
    Perhaps you are confusing me (and perhaps yourself) by talking of the name of the element when you mean the value of the attribute named "name". Perhaps in your assertion you should replace node-name(.) by @name. Commented Nov 4, 2017 at 22:59

Not the answer you're looking for? Browse other questions tagged or ask your own question.