views:

248

answers:

1

I've been trying to get the UNIQUE constraint placed on some attributes i have in a fairly basic XSD Schema. I'm using XMLSpy and i'm wanting to put a unique constraint around TEMPLATE.ID for my nodes (ie its important that they remain unique).

I've put the below in place and tried the following:

Secenario 1

<xs:unique name="uniqueviewid">
<xs:selector xpath="./views"/>
<xs:field xpath="@id"/>

Result: XSD: Validates Ok. XML Validates but doesn't uphold the unique constraint (ie two or more elements with the same id aren't picked up

Scenario 2

<xs:unique name="uniqueviewid">
<xs:selector xpath="views"/>
<xs:field xpath="@id"/>

*Results Same as Scenario 1. XSD Validates, XML Validates but ignores duplicate @id in view element

Scenario 3

<xs:unique name="uniqueviewid">
<xs:selector xpath="*"/>
<xs:field xpath="@id"/>

Results: XSD Validates and XML Validats and it respects the UNIQUE constrint (ie if duplicate views with @id it throws an invaldation as per design).

Problem is that the wild card is "*" which means all subnodes under VIEWPODS will be validated, which isnot what I want. I instead want the contraint to be focused on VIEWPOS/VIEWS/@ID exact path.

I think my XPATH is all wrong but i can't think of what i'm doing specifically wrong?


The example XML.

This is the example XML.

<config xmlns="http://tempuri.org/RIAGenicConfig.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://tempuri.org/RIAGenicConfig.xsd RIAGenicConfig.xsd">
<view>
 <viewpods>
  <views id="view1"/>
  <views id="view1"/>
 </viewpods>
</view>

The XSD in Question.

<xs:schema xmlns="http://tempuri.org/RIAGenicConfig.xsd" xmlns:mstns="http://tempuri.org/RIAGenicConfig.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://tempuri.org/RIAGenicConfig.xsd" elementFormDefault="qualified" id="RIAGenicConfig">
<xs:element name="config">
 <xs:complexType>
  <xs:sequence>
   <xs:element name="view">
    <xs:complexType>
     <xs:choice>
      <xs:element name="viewpods">
       <xs:complexType>
        <xs:choice>
         <xs:element name="views" maxOccurs="unbounded">
          <xs:complexType>
           <xs:attribute name="id"/>
          </xs:complexType>
         </xs:element>
         <xs:element name="blah"/>
        </xs:choice>
       </xs:complexType>
       <xs:unique name="uniqueviewid">
        <xs:selector xpath="*"/>
        <xs:field xpath="@id"/>
       </xs:unique>
      </xs:element>
     </xs:choice>
    </xs:complexType>
   </xs:element>
  </xs:sequence>
 </xs:complexType>
</xs:element>

+2  A: 

Qualify the xpath selection for mstns:views instead of *(all elements):

<xs:unique name="uniqueviewid">
  <xs:selector xpath="mstns:views"/>
   <xs:field xpath="@id"/>
</xs:unique>
Mads Hansen
You are my hero ;)
Scott Barnes
Where did the mstns come from?
tenpn
From the XSD. It contains the namespace definition: xmlns:mstns="http://tempuri.org/RIAGenicConfig.xsd"
Mads Hansen
Thanks. My xml schema had set xmlns to be the same as my target xml, which I thought would be enough. I added a sub-namespace (is that what you'd call it?) to the schema and used that for my xpaths and now everything works. \o/
tenpn