DirtyDiddy
DirtyDiddy

Reputation: 3

XSD - Unique statement doesn't prevent duplicates

im working on a XSD for some products index. Hope you don't mind me posting the code with German names ;) The problem is: I want my "artikelgruppe" (=Product-Group) to have a unique "GRUPPE" (=GroupNumber). Same goes for "artikel"/"ARTNR".

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="artikelkatalog">
    <xsd:complexType>
        <xsd:sequence>
            <xsd:element name="artikelgruppen">
                <xsd:complexType>
                    <xsd:sequence>
                        <xsd:element name="artikelgruppe" maxOccurs="unbounded">
                            <xsd:complexType>
                                <xsd:sequence>
                                    <xsd:element name="GRUPPE" type="xsd:integer">
                                    </xsd:element>
                                    <xsd:element name="GRUP_TXT" type="xsd:string">
                                    </xsd:element>
                                </xsd:sequence>
                            </xsd:complexType>
                        </xsd:element>
                    </xsd:sequence>
                </xsd:complexType>
                <xsd:unique name="unique_GRUPPE">
                <xsd:selector xpath="artikelgruppe" />
                <xsd:field xpath="@GRUPPE" />
                </xsd:unique>
            </xsd:element>
        <xsd:element name="alle_artikel">
            <xsd:complexType>
                <xsd:sequence>
                    <xsd:element name="artikel" minOccurs="0" maxOccurs="unbounded">
                        <xsd:complexType>
                            <xsd:sequence>
                                <xsd:element name="ARTNR" type="xsd:integer">
                                </xsd:element>
                                <xsd:element name="ARTBEZ" type="xsd:string">
                                </xsd:element>
                                <xsd:element name="EKPREIS" type="xsd:float">
                                </xsd:element>
                                <xsd:element name="EKWAEHRUNG" type="xsd:string">
                                </xsd:element>
                                <xsd:element name="VPREIS" type="xsd:float">
                                </xsd:element>
                                <xsd:element name="VWAEHRUNG" type="xsd:string">
                                </xsd:element>
                                <xsd:element name="GRUPPE" type="xsd:integer">
                                </xsd:element>
                            </xsd:sequence>
                        </xsd:complexType>
                    </xsd:element>
                </xsd:sequence>
            </xsd:complexType>
            <xsd:unique name="unique_ARTNR">
            <xsd:selector xpath="artikel" />
            <xsd:field xpath="@ARTNR" />
            <!--<xsd:keyref name="keyref_GRUPPE_REFERENZ" refer="unique_ARTNR">
            <xsd:selector xpath="artikelgruppe" />
            <xsd:field xpath="@ARTNR"/>
            </xsd:keyref>-->
            </xsd:unique>
        </xsd:element>
        </xsd:sequence>
    </xsd:complexType>
</xsd:element>

My code causes no errors, but doesn't do the job :( I fed this:

<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<artikelkatalog>
    <artikelgruppen>
        <artikelgruppe>
            <GRUPPE>20</GRUPPE>
            <GRUP_TXT>Workstation</GRUP_TXT>
        </artikelgruppe>
        <artikelgruppe>
            <GRUPPE>20</GRUPPE>
            <GRUP_TXT>Server</GRUP_TXT>
        </artikelgruppe>
        <artikelgruppe>
            <GRUPPE>30</GRUPPE>
            <GRUP_TXT>Monitor</GRUP_TXT>
        </artikelgruppe>
    </artikelgruppen>
    <alle_artikel>
        <artikel>
            <ARTNR>1100</ARTNR>
            <ARTBEZ>Transtec 800</ARTBEZ>
            <EKPREIS>720.00</EKPREIS>
            <EKWAEHRUNG>€</EKWAEHRUNG>
            <VPREIS>749.00</VPREIS>
            <VWAEHRUNG>€</VWAEHRUNG>
            <GRUPPE>10</GRUPPE>
        </artikel>
        <artikel>
            <ARTNR>1100</ARTNR>
            <ARTBEZ>Trinitron 17"</ARTBEZ>
            <EKPREIS>375.00</EKPREIS>
            <EKWAEHRUNG>$</EKWAEHRUNG>
            <VPREIS>399.00</VPREIS>
            <VWAEHRUNG>$</VWAEHRUNG>
            <GRUPPE>20</GRUPPE>
        </artikel>
    </alle_artikel>
</artikelkatalog>

And the machine was fine with it :( What's the matter? See the uncommented keyref statement? That would be cherry on top ;) Thank you so much.

Upvotes: 0

Views: 335

Answers (1)

Meyer
Meyer

Reputation: 1712

In an XPath expression, the @ character selects an attribute. However, in your example, the keys are stored as element values, not as attributes. Simply remove @ from the field selectors and the uniqueness constraints should work fine:

<xsd:field xpath="GRUPPE" />
...
<xsd:field xpath="ARTNR" />

The commented section does not make much sense, because there is no ARTNR in artikelgruppe. I assume you would like to reference the GRUPPE number between the two element groups.

In that case, the keyref has to be specified in a common ancestor element, i.e. artikelkatalog:

<xsd:element name="artikelkatalog">
  <xsd:complexType>
  ...
  </xsd:complexType>

  <xsd:keyref name="keyref_GRUPPE_REFERENZ" refer="unique_GRUPPE">
    <xsd:selector xpath="alle_artikel/artikel" />
    <xsd:field xpath="GRUPPE"/>
  </xsd:keyref>

</xsd:element>

Upvotes: 1

Related Questions