1

I'm trying to put a key in sequence and am being bombarded with errors. It seems I can't do this. Additionally, I am being told my key needs a field and selector, which I have been able to find very little documentation on. (In fact, in desperation, I downloaded Liquid XML Studio [vs. Notepad] and searched it's help files. . . to find NO even reference to the word "selector") Regardless - what is another method I can use to guarantee a unique, not null value for an element, within a sequence? (The content in question is a string)

Please note that without the key element, the schema validates.

The error

Invalid per cvc-complex-type.1.2.4: element {http://www.w3.org/2001/XMLSchema}:key not allowed here (1) in element {http://www.w3.org/2001/XMLSchema}:sequence, expecting [{http://www.w3.org/2001/XMLSchema}:annotation, $, {http://www.w3.org/2001/XMLSchema}:element, {http://www.w3.org/2001/XMLSchema}:group, {http://www.w3.org/2001/XMLSchema}:choice, {http://www.w3.org/2001/XMLSchema}:sequence, {http://www.w3.org/2001/XMLSchema}:any]:

The schema

<?xml version="1.0"?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
 targetNamespace="READOO" elementFormDefault="qualified">

  <xs:element name="ReferralCollection">
    <xs:complexType>
      <xs:sequence>
    <xs:key name="URL" type="string" />
        <xs:element maxOccurs="unbounded" name="keyword">
          <xs:complexType>
            <xs:simpleContent>
              <xs:extension base="xs:string">
                <xs:attribute name="occurrences" type="xs:int" use="required" />
              </xs:extension>
            </xs:simpleContent>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

</xs:schema>
4
  • @john, why did you delete my note of a problem? I realize that it should be taken to meta, but to simply delete it, unless you addressed the problem as well, seems quick-handed. Commented Oct 10, 2009 at 19:29
  • let me know if this workaround doesn't. See: meta.stackexchange.com/questions/25424/… for discussion on this bug. Commented Oct 10, 2009 at 19:42
  • My mistake, I made several edits and must've trampled over your comment while doing so. Commented Oct 10, 2009 at 19:55
  • @john, no problem, I'll just take it to meta myself Commented Oct 10, 2009 at 19:56

2 Answers 2

2

The key element is not supposed to go inside the sequence element. Instead, you put it as a child of the xs:element that defines ReferralCollection. The selector and field are child elements of the key element that define what is supposed to be unique. Both are XPath expressions. The selector value sets up the XPath context, and the field elements (there can be more than one) define the combination of values that are supposed to be unique. So in your case, the key element might look something like this:

<xs:key name="URL">
  <xs:selector xpath="."/>
  <xs:field xpath="rd:keyword"/>
</xs:key>

The selector here selects the element itself, that is, ReferralCollection. Then, in that context, the field element denotes the values of the keyword elements, which are thus constrained to be unique. The value of an element in XPath is its text content.

I haven't done much with key elements (or XML Schema in general), so some details above might not be correct, but the basic idea is what I explained, so it should be easy to fix any mistakes I made. Oh, also note that I used the rd prefix for your READOO namespace; in my experience using explicit prefixes is always best when dealing with XPath, so you need the appropriate xmlns:rd attribute in your schema to make this work.

EDIT: So it seems you want something like this:

<xs:element name="ReferralCollection">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="URL" maxOccurs="unbounded">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="stem" type="xsd:string"/>
            <xs:element name="keyword" maxOccurs="unbounded">
            ...
            </xs:element>
          ...
  </xs:complexType>

  <xs:key name="URL">
    <xs:selector xpath="./URL"/>
    <xs:field xpath="stem"/>
  </xs:key>
</xs:element>

Is this closer to what you meant? It has URL elements, one or more, each containing a stem element followed by one or more keyword elements. The key constraint should make the contents of the stem elements unique.

Sign up to request clarification or add additional context in comments.

13 Comments

thanks for your help!, however, perhaps ironically, when I include the key within ReferralCollection, I am then given an error that complexType is invalid. If I put it within the complexType but outside of the sequence, I am again told that the key is invalid.
Do you put the key element after the complexType element inside ReferralCollection? Because those two elements are acceptable only in that order.
I didn't until I looked @Rubens answer. So does this mean it's simply impossible to force the key to be in sequence? I'd really like to mandate that it come first. Also, would you mind explaining why you used the prefix (which I ended up having to delete actually for my validator) instead of the @ sign (whatsit mean?) that I see elsewhere? [my validator validates it with and without the @ sign interestingly]
What do you mean by "key to be in sequence"? In essence, key provides some additional constraints on top of what you can define with the other parts of XML Schema, so it is not really a part of the content description but beside it, so it would not be appropriate to have it inside a content model description.
The @ sign signifies an attribute. Since in your schema the unique part is not an attribute value but text content, you shouldn't have it. And if your documents are valid, they will validate even when the key constraints are improperly written. Try to validate a document that follows the grammar but violates the key constraint that you want, and see whether it works then.
|
0

Please, see if this links can help you:

EDIT: I built schema below several years ago; please, see it fits in your problem:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    targetNamespace="urn:asp4d"
    xmlns:asp4d="urn:asp4d">
  <xs:element name="ASP4Developers">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Links" minOccurs="1" maxOccurs="1">
          <xs:keyref name="kUserId" refer="asp4d:UserId">
            <xs:selector xpath="Link"/>
            <xs:field xpath="@UserId"/>
          </xs:keyref>
        </xs:element>
      </xs:sequence>
    </xs:complexType>

    <xs:key name="UserId">
      <xs:selector xpath="Users/User"/>
      <xs:field xpath="@UserId"/>
    </xs:key>

  </xs:element>

</xs:schema>

3 Comments

while this does provide more documentation, it does not address my principle problem of needing a key in sequence (unless I am missing something)
interesting, seeing this I tried putting the key after the complexType as you showed, and it worked! But is there no way for it to come first? That seems bizarre.
a key can be used in several places inside your xsd, so makes sense having a broader scope

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.