2010-01-06 6 views
10

Я пытаюсь реализовать очень простое ограничение схемы XML.XSD key/keyref beginner question

IDREF атрибут на элементах типа <Batz> должны только быть разрешено иметь значение, которое соответствует в ID атрибут по крайней мере один элемент < бар >.

Если это не имеет для вас никакого смысла, пожалуйста, просто взгляните на приведенный ниже пример XML-документа, я думаю, что это на самом деле объясняет это лучше, чем моя попытка выразить его словами.

Итак, вопрос: Почему xmllint пропускает приведенную ниже схему схемы/xml (она говорит, что документ действителен)? Как исправить это, чтобы достичь желаемого ограничения?

Схема:

<?xml version="1.0"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="test" xmlns="test" elementFormDefault="qualified"> 

    <xs:element name="foo"> 
     <xs:complexType> 
      <xs:sequence> 
       <xs:element name="bar" minOccurs="0" maxOccurs="unbounded"> 
        <xs:complexType> 
         <xs:attribute name="id" use="required" type="xs:string" /> 
        </xs:complexType> 
       </xs:element> 
       <xs:element name="batz" minOccurs="0" maxOccurs="unbounded"> 
        <xs:complexType> 
         <xs:attribute name="idref" use="required" type="xs:string" /> 
        </xs:complexType> 
       </xs:element> 
      </xs:sequence> 
     </xs:complexType> 

     <xs:key name="ID"> 
      <xs:selector xpath="./bar" /> 
      <xs:field xpath="@id" /> 
     </xs:key> 

     <xs:keyref name="IDREF" refer="ID"> 
      <xs:selector xpath="./batz" /> 
      <xs:field xpath="@idref" /> 
     </xs:keyref> 

    </xs:element> 
</xs:schema> 

Документ:

<?xml version="1.0"?> 
<foo xmlns="test"> 
    <bar id="1" /> 
    <bar id="2" /> 
    <batz idref="1" /> <!-- this should succeed because <bar id="1"> exists --> 
    <batz idref="3" /> <!-- this should FAIL --> 
</foo> 

ответ

2

Ваш XML документ, как показано на рисунке, не включает в себя schemaLocation. Когда XML-документ не ссылается на схему или DTD, он может проходить проверку просто путем корректного XML. (Это когда-то случалось с сотрудником, использующим другой валидатор. Я думаю, что это ошибка, которую валидатор не предупредил, что у нее отсутствует схема или DTD. Но я отвлекаюсь.)

В любом случае , вероятно, должно быть что-то вроде:

<?xml version="1.0"?> 
<foo 
    xmlns="test" <!-- This is bad form, by the way... --> 
    xsi:schemaLocation="test /path/to/schema/document" 
    <bar id="1" /> 
    <bar id="2" /> 
    <batz idref="1" /> <!-- this should succeed because <bar id="1"> exists --> 
    <batz idref="3" /> <!-- this should FAIL --> 
</foo> 
+0

Спасибо! Это была проблема. – razorline

+1

Используя это, он все еще проверяется в некоторых валидаторах. Но, конечно, вам нужно обратиться к схеме. –

7

Даже с назначенным расположением схемы это не будет работать во всех синтаксических анализаторах.

<?xml version="1.0"?> 
<foo xmlns="test" 
    xsi:schemaLocation="test test.xsd" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <bar id="1" /> 
    <bar id="2" /> 
    <batz idref="1" /> <!-- this should succeed because <bar id="1"> exists --> 
    <batz idref="3" /> <!-- this should FAIL --> 
</foo> 

Это также подтвердит, поскольку ключ не ссылается на целевое пространство имен.

Изменения, которые должны быть сделаны в XSD являются

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

И

<xs:key name="ID"> 
    <xs:selector xpath="./t:bar" /> 
    <xs:field xpath="@id" /> 
</xs:key> 

<xs:keyref name="IDREF" refer="ID"> 
    <xs:selector xpath="./t:batz" /> 
    <xs:field xpath="@idref" /> 
</xs:keyref> 

Для обсуждения по поводу такого поведения см #1545101

Смежные вопросы