I have following xml and xsd as basic example for my question:
XML
<parentgroup>
<parent id="1">
<child id="2" />
<child id="3" />
<childgroup id="4">
<child id="5" />
<child id="2" />
</childgroup>
<child id="5" />
</parent>
<parent id="2">
<childgroup id="33">
<child id="1" />
<child id="4" />
</childgroup>
<child id="1" />
<child id="5" />
<childgroup id="4">
<child id="1" />
<child id="6" />
</childgroup>
</parent>
</parentgroup>
XSD
<xsd:element name="parentgroup" type="parentgroup">
<xsd:unique name="UniqueParentId">
<xsd:selector xpath="child::parent"></xsd:selector>
<xsd:field xpath="@id"></xsd:field>
</xsd:unique>
</xsd:element>
<xsd:complexType name="parentgroup">
<xsd:sequence maxOccurs="unbounded">
<xsd:element name="parent" type="parent" maxOccurs="unbounded" minOccurs="1">
<xsd:unique name="UniqueChildId">
<xsd:selector xpath=".//*"></xsd:selector>
<xsd:field xpath="@id"></xsd:field>
</xsd:unique>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:int" />
</xsd:complexType>
<xsd:complexType name="parent">
<xsd:choice maxOccurs="unbounded" minOccurs="1">
<xsd:element name="child" type="child" maxOccurs="unbounded" minOccurs="1"></xsd:element>
<xsd:element name="childgroup" type="childgroup" maxOccurs="unbounded" minOccurs="1"></xsd:element>
</xsd:choice>
<xsd:attribute name="id" type="xsd:int" />
</xsd:complexType>
<xsd:complexType name="childgroup">
<xsd:sequence maxOccurs="unbounded">
<xsd:element name="child" type="child" maxOccurs="unbounded" minOccurs="1"></xsd:element>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:int" />
</xsd:complexType>
<xsd:complexType name="child">
<xsd:attribute name="id" type="xsd:int" />
</xsd:complexType>
Task
- All parents have an unique “id” attr. and no child has the same “id” attr. like his parent.
- Childs and Childgroups in a parent have unique “id” attr. excluding the Childs in the Childgroup. (ids are unique in the first depth plus parent)
- Childs in a Childgroup have unique “id” attr. (so it is allowed that the ids of childs in a childgroup are equal to ids of childs out of the childgroup in the same parent, but its not allowed that it is euqal to id of own childgroup, like 2. point [(ids are unique in the first depth plus parent)] )
1. Question
The points 1. and 2. are clear, but I dont know how to exclude the descendant of childgroup, i tried following but get always xpath syntax error
First Try
<xsd:element name="parent" type="parent" maxOccurs="unbounded" minOccurs="1">
<xsd:unique name="UniqueChildId">
<xsd:selector xpath=".//*[not(childgroup)]"></xsd:selector>
<xsd:field xpath="@id"></xsd:field>
</xsd:unique>
</xsd:element>
Second Try
<xsd:element name="parent" type="parent" maxOccurs="unbounded" minOccurs="1">
<xsd:unique name="UniqueChildId">
<xsd:selector xpath=".//*[not(child::childgroup)]"></xsd:selector>
<xsd:field xpath="@id"></xsd:field>
</xsd:unique>
</xsd:element>
Third Try
<xsd:element name="parent" type="parent" maxOccurs="unbounded" minOccurs="1">
<xsd:unique name="UniqueChildId">
<xsd:selector xpath="child::*[not(childgroup)]"></xsd:selector>
<xsd:field xpath="@id"></xsd:field>
</xsd:unique>
</xsd:element>
Thanks for your help!
Invalid Xml
E.g.1
<parentgroup>
<parent id="1">
<child id="2" />
<child id="3" />
<childgroup id="7">
<child id="5" />
<child id="6" />
</childgroup>
<child id="7" />
</parent>
<parent id="8">
<childgroup id=9">
<child id="10" />
<child id="9" />
</childgroup>
<child id="12" />
<child id="13" />
<childgroup id="14">
<child id="15" />
<child id="16" />
</childgroup>
</parent>
</parentgroup>
Reason
- Invalid because in first parent: childgroup id=”7″ has same id as child id=”7″
- Invalid because in second parent: child id=”9″ has same id as his “father” childgroup id=”9″
E.g.2
<parentgroup>
<parent id="1">
<child id="2" />
<child id="3" />
<childgroup id="4">
<child id="5" />
<child id="7" />
</childgroup>
<child id="7" />
</parent>
<parent id="8">
<childgroup id=9">
<child id="10" />
<child id="8" />
</childgroup>
<child id="12" />
<child id="14" />
<childgroup id="14">
<child id="15" />
<child id="16" />
</childgroup>
</parent>
</parentgroup>
Reason
- Invalid because in second parent: childgroup id=”14″ has same id as child id=”14″
E.g.2
<parentgroup>
<parent id="1">
<child id="2" />
<child id="7" />
<childgroup id="4">
<child id="5" />
<child id="6" />
</childgroup>
<child id="7" />
</parent>
<parent id="8">
<childgroup id=9">
<child id="10" />
<child id="11" />
</childgroup>
<child id="12" />
<child id="14" />
<childgroup id="15">
<child id="16" />
<child id="11" />
</childgroup>
</parent>
</parentgroup>
Reason
- Invalid because in first parent: child id=”7″ has same id as child id=”7″
E.g.2
<parentgroup>
<parent id="1">
<child id="2" />
<child id="3" />
<childgroup id="4">
<child id="1" />
<child id="2" />
</childgroup>
<child id="7" />
</parent>
<parent id="8">
<childgroup id=9">
<child id="10" />
<child id="11" />
</childgroup>
<child id="12" />
<child id="14" />
<childgroup id="9">
<child id="16" />
<child id="11" />
</childgroup>
</parent>
</parentgroup>
Reason
- Invalid because in second parent: childgroup id=”9″ has same id as childgroup id=”9″
Valid Xml
E.g.1
<parentgroup>
<parent id="1">
<child id="2" />
<child id="3" />
<childgroup id="4">
<child id="5" />
<child id="6" />
</childgroup>
<child id="7" />
</parent>
<parent id="8">
<childgroup id=1">
<child id="2" />
<child id="3" />
</childgroup>
<child id="4" />
<child id="5" />
<childgroup id="6">
<child id="7" />
<child id="9" />
</childgroup>
</parent>
</parentgroup>
E.g.2
<parentgroup>
<parent id="1">
<child id="2" />
<child id="3" />
<childgroup id="4">
<child id="5" />
<child id="7" />
</childgroup>
<child id="7" />
</parent>
<parent id="8">
<childgroup id=1">
<child id="2" />
<child id="5" />
</childgroup>
<child id="4" />
<child id="5" />
<childgroup id="6">
<child id="2" />
<child id="5" />
</childgroup>
</parent>
</parentgroup>
I’ve cleaned up and corrected your errors. Below is the new XSD that works with the posted XML and the requirements the way I understood them. I hope the diagram below helps you visualize better the constraints and the XPath you should use.
The modified XSD:
UPDATE: The XSD works fine with all sample XMLs. Here is what QTAssistant is saying about each:
Invalid:
E.g. 1:
Error occurred while loading [], line 9 position 4There is a duplicate key sequence '7' for the 'UniqueChildId' key or unique identity constraint.
Error occurred while loading [], line 15 position 5
There is a duplicate key sequence '9' for the 'UniqueChildIdInChildGroup' key or unique identity constraint.
ParentChildChildGroup-Inv-Eg1.xml is invalid.
E.g. 2:
Error occurred while loading [], line 21 position 5There is a duplicate key sequence '14' for the 'UniqueChildId' key or unique identity constraint.
ParentChildChildGroup-Inv-Eg2.xml is invalid.
E.g. 2 (3?):
Error occurred while loading [], line 9 position 4There is a duplicate key sequence '7' for the 'UniqueChildId' key or unique identity constraint.
ParentChildChildGroup-Inv-Eg3.xml is invalid.
E.g. 2 (4?):
Error occurred while loading [], line 21 position 5There is a duplicate key sequence '9' for the 'UniqueChildId' key or unique identity constraint.
ParentChildChildGroup-Inv-Eg4.xml is invalid.
What you described as valid XMLs are successfully validated.