Гость
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / xsd:keyref видимость ключа / 2 сообщений из 2, страница 1 из 1
19.08.2017, 17:07
    #39507871
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
xsd:keyref видимость ключа
Правильно ли я понимаю, чтобы в XML валидировалась ссылочная целостность, элементы xsd:key и xsd:keyref должны быть объявлены в одном и том же элементе xsd:element (сами селекторы могут указывать куда угодно). Если это верно, то как тогда трактовать фразу
refer Required. Specifies the name of a key or unique element defined in this or another schemaКак их можно объявить в разных схемах, если они должны иметь одного родителя?

С уважением, Vasilisk
...
Рейтинг: 0 / 0
19.08.2017, 19:15
    #39507897
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
xsd:keyref видимость ключа
Все оказалось не так просто. Вот полное "расследование"

Есть XML

Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation="test.xsd">
  <main>
    <id>1</id>
    <id>2</id>
  </main>
  <ref>
    <id>1</id>
    <id>1</id>
  </ref>
</root>


задача - элементы ref/id должны ссылаться на существующие элементы main/id . Вот такая схема

Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  elementFormDefault="qualified">
  <xsd:element name="root">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="main" maxOccurs="unbounded">
          <xsd:complexType>
            <xsd:sequence>
              <xsd:element name="id" type="xsd:integer" maxOccurs="unbounded"/>
            </xsd:sequence>
          </xsd:complexType>
        </xsd:element>
        
        <xsd:element name="ref">
          <xsd:complexType>
            <xsd:sequence>
              <xsd:element name="id" type="xsd:integer" maxOccurs="unbounded"/>
            </xsd:sequence>
          </xsd:complexType>
        </xsd:element>
      </xsd:sequence>
    </xsd:complexType>

    <xsd:key name="key">
      <xsd:selector xpath="main/id"/>
      <xsd:field xpath="."/>
    </xsd:key>
    <xsd:keyref name="ref" refer="key">
      <xsd:selector xpath="ref/id"/>
      <xsd:field xpath="."/>
    </xsd:keyref>
  </xsd:element>
</xsd:schema>


все отлично валидирует

Теперь я хочу спрятать ключи в соответствующие элементы (основная цель - вынести описание main с ключом в отдельную схему) и пишу вот такую схему

Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  elementFormDefault="qualified">
  <xsd:element name="root">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="main" maxOccurs="unbounded">
          <xsd:complexType>
            <xsd:sequence>
              <xsd:element name="id" type="xsd:integer" maxOccurs="unbounded"/>
            </xsd:sequence>
          </xsd:complexType>
          <xsd:key name="key">
            <xsd:selector xpath="id"/>
            <xsd:field xpath="."/>
          </xsd:key>
        </xsd:element>
        
        <xsd:element name="ref">
          <xsd:complexType>
            <xsd:sequence>
              <xsd:element name="id" type="xsd:integer" maxOccurs="unbounded"/>
            </xsd:sequence>
          </xsd:complexType>
        </xsd:element>
      </xsd:sequence>
    </xsd:complexType>

    <xsd:keyref name="ref" refer="key">
      <xsd:selector xpath="ref/id"/>
      <xsd:field xpath="."/>
    </xsd:keyref>
  </xsd:element>
</xsd:schema>


Xerces говорит, что документ по прежнему валиден, а вот MSXML6 начинает ругаться
MSXMLДля ограничения по идентификатору "ref" ссылка на ключ keyref "key" не сопоставляется ключу.

Далее, проводим следующий эксперимент xsd:key делаем глобальным, а xsd:keyref прячем в элемент ref

Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  elementFormDefault="qualified">
  <xsd:element name="root">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="main" maxOccurs="unbounded">
          <xsd:complexType>
            <xsd:sequence>
              <xsd:element name="id" type="xsd:integer" maxOccurs="unbounded"/>
            </xsd:sequence>
          </xsd:complexType>
        </xsd:element>
        
        <xsd:element name="ref">
          <xsd:complexType>
            <xsd:sequence>
              <xsd:element name="id" type="xsd:integer" maxOccurs="unbounded"/>
            </xsd:sequence>
          </xsd:complexType>
          <xsd:keyref name="ref" refer="key">
            <xsd:selector xpath="id"/>
            <xsd:field xpath="."/>
          </xsd:keyref>
        </xsd:element>
      </xsd:sequence>
    </xsd:complexType>

    <xsd:key name="key">
      <xsd:selector xpath="main/id"/>
      <xsd:field xpath="."/>
    </xsd:key>
  </xsd:element>
</xsd:schema>


Теперь поведение валидаторов меняется с точностью до наоборот

Xerces выдает
Xerces Identity Constraint error: identity constraint "KeyRef@1c5960f" has a keyref which refers to a key or unique that is out of scope.

А MSXML говорит, что документ валиден

Ну и наконец, я попробовал оба элемента xsd:key и xsd:keyref спрятать в свои элементы

Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  elementFormDefault="qualified">
  <xsd:element name="root">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="main" maxOccurs="unbounded">
          <xsd:complexType>
            <xsd:sequence>
              <xsd:element name="id" type="xsd:integer" maxOccurs="unbounded"/>
            </xsd:sequence>
          </xsd:complexType>
          <xsd:key name="key">
            <xsd:selector xpath="id"/>
            <xsd:field xpath="."/>
          </xsd:key>
        </xsd:element>
        
        <xsd:element name="ref">
          <xsd:complexType>
            <xsd:sequence>
              <xsd:element name="id" type="xsd:integer" maxOccurs="unbounded"/>
            </xsd:sequence>
          </xsd:complexType>
          <xsd:keyref name="ref" refer="key">
            <xsd:selector xpath="id"/>
            <xsd:field xpath="."/>
          </xsd:keyref>
        </xsd:element>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>


Схема осталась валидной, а на документ оба валидатора стали ругаться
XercesIdentity Constraint error: identity constraint "KeyRef@11145ed" has a keyref which refers to a key or unique that is out of scope.

MSXMLДля ограничения по идентификатору "ref" ссылка на ключ keyref "key" не сопоставляется ключу.

Вопрос следующий: кто прав? Т.к. нигде в документации я не нашел ограничений на то, где могут быть объявлены xsd:key и xsd:keyref . Можно ли как-то заставить работать последний вариант схемы? Если нет, то можно ли убедить MSXML работать с "локальным" ключом? Судя по фразе с MSDN

MSDN refer

Имя элемента key или unique, определенного в этой схеме ( или в другой схеме , обозначенной в указанном пространстве имен). Значение refer должно быть полным именем (QName). Этот тип может включать префикс пространства имен.

Вариант с "локальным" ключом должен работать. Иначе как бы его можно было бы перенести в другую схему?
...
Рейтинг: 0 / 0
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / xsd:keyref видимость ключа / 2 сообщений из 2, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]