Using XPath for Identity Constraint of Elements and Attributes

Hi to all, I have an XML schema document that looks like this :

< xml version="1.0" >
<xs:schema id="Employees" targetNamespace="
http://tempuri.org/Employee.xsd" xmlns:mstns="http://tempuri.org/Employee.xsd"
  xmlns="
http://tempuri.org/Employee.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
  attributeFormDefault="qualified" elementFormDefault="qualified">
  <xs:element name="Employees" msdata:IsDataSet="true" msdata:EnforceConstraints="False">
    <xs:complexType>
      <xs:choice maxOccurs="unbounded">
        <xs:element name="Employee">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="Firstname" type="xs:string" minOccurs="1" msdata:Ordinal="0" maxOccurs="1" />
              <xs:element name="Lastname" type="xs:string" minOccurs="1" msdata:Ordinal="1" maxOccurs="1" />
            </xs:sequence>
            <xs:attribute name="empId" form="unqualified" type="xs:byte" use="required" />
          </xs:complexType>
          <xs:key name="EmployeeKey">
            <xs:selector xpath="Employee" />
            <xs:field xpath="
Employee/@empId" />
          </xs:key>
        </xs:element>
      </xs:choice>
    </xs:complexType>
  </xs:element>
</xs:schema>

I want to test whether the schema that I created validates against an instance document. Below is my sample instance document.

< xml version="1.0" encoding="utf-8" >
<Employees xmlns="
http://tempuri.org/Employee.xsd">
  <Employee empId="1">
    <Firstname>John</Firstname>
    <Lastname>Doe</Lastname>
  </Employee>
  <Employee empId="1">
    <Firstname>Jane</Firstname>
    <Lastname>Doe</Lastname>
  </Employee>
</Employees>

As we should expect, the instance document will be invalidated since both <Employee> elements have the same empId attribute (empId="1"). When I validate this instance document against the schema that I created, it is recognized as a valid XML document. What could be the problem Is there a syntax error in my XPath declaration



Answer this question

Using XPath for Identity Constraint of Elements and Attributes

  • thomsson

    Thank you sir. May I ask, what is the "mstns" for Is it a namespace I'm really not familiar yet with how namespaces are implemented. Actually, I also tried placing the <xs:key> element in that same spot and have a selector element of <xs:selector xpath="*" />.. From what I've read and understood, it queries every child element of the <Employees> element, which is not a good practice because, I'm not specifying which child element to query. Is that a good practice sir

    By the way, how about, the order of the attribute values In my specifications, there should at least be 1 <Employee> element. Maybe I can just use the minOccurs and maxOccurs attributes. But what if the case below happens :

    < xml version="1.0" encoding="utf-8" >
    <Employees xmlns="
    http://tempuri.org/Employee.xsd">
      <Employee empId="2">
        <Firstname>Jane</Firstname>
        <Lastname>Doe</Lastname>
      </Employee>
      <Employee empId="1">
        <Firstname>John</Firstname>
        <Lastname>Doe</Lastname>
      </Employee>
    </Employees>

    I want this to be invalid because the <Employee empId="2"> comes first before <Employee empId="1">. How can I implement this in XML Schema Woud the AutoIncrement attribute of the empId attribute be enough Below is another invalid instance document :

    < xml version="1.0" encoding="utf-8" >
    <Employees xmlns="
    http://tempuri.org/Employee.xsd">
      <Employee empId="1">
        <Firstname>Jane</Firstname>
        <Lastname>Doe</Lastname>
      </Employee>
      <Employee empId="3">
        <Firstname>John</Firstname>
        <Lastname>Doe</Lastname>
      </Employee>
    </Employees>

    This one becomes an invalid document too because it has an <Employee empId="3"> element whereas the <Employee empId="2"> is missing. How can I implement my Schema with the requirements above Sir, can you teach me more I'm sorry because I'm really just new to XML. Thank you once again.


  • RookieDBA

    Thank you very much sir.
  • FassaBortolo

    Ah i see now. But can't we just use the one below since Employee is "local" to the document

    <xs:key name="EmployeeKey">
        <xs:selector xpath="Employee" />
        <xs:field xpath="
    @empId" />
    </xs:key>

    Should xpath attributes always have to have qualified elements


  • linker

    jcarlos.net wrote:

    May I ask, what is the "mstns" for Is it a namespace I'm really not familiar yet with how namespaces are implemented.

    mstns is a prefix defined in the namespace declaration xmlns:mstns="http://tempuri.org/Employee.xsd" the schema contains. So the target namespace your schema defines has the name http://tempuri.org/Employee.xsd and the schema through xmlns:mstns="http://tempuri.org/Employee.xsd" binds the prefix mstns to that namespace to allow the use of the prefix to qualify names in XPath (or other places in the schema that might be useful for instance a ref attribute).



  • NeilL

    This schema works as you want it, the xs:key element has been moved to the parent element and the XPath has been fixed to select the element in the target namespace:

    <xs:schema id="Employees" targetNamespace="http://tempuri.org/Employee.xsd" xmlns:mstns="http://tempuri.org/Employee.xsd"
    xmlns="http://tempuri.org/Employee.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
    attributeFormDefault="qualified" elementFormDefault="qualified">
    <xs:element name="Employees" msdata:IsDataSet="true" msdata:EnforceConstraints="False">
    <xs:complexType>
    <xs:choice maxOccurs="unbounded">
    <xs:element name="Employee">
    <xs:complexType>
    <xs:sequence>
    <xs:element name="Firstname" type="xs:string" minOccurs="1" msdata:Ordinal="0" maxOccurs="1" />
    <xs:element name="Lastname" type="xs:string" minOccurs="1" msdata:Ordinal="1" maxOccurs="1" />
    </xs:sequence>
    <xs:attribute name="empId" form="unqualified" type="xs:byte" use="required" />
    </xs:complexType>
    </xs:element>
    </xs:choice>
    </xs:complexType>
    <xs:key name="EmployeeKey">
    <xs:selector xpath="mstns:Employee" />
    <xs:field xpath="@empId" />
    </xs:key>
    </xs:element>
    </xs:schema>



  • XNA Rockstar

    The XPath expression "Employee" selects elements with the element name "Employee" in no namespace. As your schema defines its "Employee" elements in a certain namespace simply using the XPath expression "Employee" will never select those elements as elements with the name "Employee" in no namespace are completely different from elements with the same name which are in a certain namespace.

  • Using XPath for Identity Constraint of Elements and Attributes