xsd:ID in Relax NG Schema

1.2k views Asked by At

I have the following xml file

<bookshop>
<book bid="1"> Programming in C# </book>
<book bid="2"> programming in Java </book>
<authors>
 <author bidref="1"> person1 </author>
 <author bidref="2"> person2 </author>
 <author bidref="1"> person3 </author>
</authors>
</bookshop>

then I made the following Relax NG schema

start=element bookshop{
element book {attribute bid{xsd:ID},
              text}
element authors{
    element author { attribute bidref{xsd:IDREF},
                         text}
               }}

However, it always gives me error said that value of attribute bid is invalid must be an XML name without colons

1

There are 1 answers

2
Nic Gibson On BEST ANSWER

OK, I've fixed the errors in your XML example. Your schema can't validate the XML you've given there because it's, well, wrong. Anyway, that's probably at least partly a copy and paste error. The schema I think you mean is below (one or more marker and sequence comma inserted):

start=

element bookshop
{
    element book {attribute bid {xsd:ID}, text}+,

    element authors
    {
        element author { attribute bidref {xsd:IDREF}, text}
    }

}

As an aside, this sort of 'russian doll' schema is horribly unmaintainable. If you are using RelaxNG you'd be better off with named patterns.

Now, your fundamental problem here is that you've modelled the attributes bid and bidref as ID and IDREF respectively. These types hark back to DTDs. An ID type is defined as matching the 'Name' production which is defined (in the same document) as:

NameStartChar ::=       ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | 
    [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | 
    [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | 
    [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | 
    [#x203F-#x2040]
Name     ::= NameStartChar (NameChar)*

In simple terms that says "you can't start an ID with a number nor can an ID be just a number". XML ID (and IDREF) values must start with a letter.

Your schema, btw, might be better expressed as:

bookshop.content = (book+, authors)
bookshop = element bookshop {bookshop.content}

book.bid = attribute bid {xsd:ID}
book.content = (book.bid, text)
book = element book {book.content}

authors.content = author+ 
authors = element authors {authors.content}

author.bidref = attribute bidref {xsd:IDREF}
author.content = (author.bidref, text)
author = element author {author.content}