Одно пространство имен XML равно одному и только одному файлу схемы? - PullRequest
22 голосов
/ 15 февраля 2011

... или Почему эти файлы проверяются в Visual Studio 2010 , но не с xmllint 1 ?

В настоящее время я работаю против опубликованной xml-схемы, в которой первоначальная авторская привычка разбивать схемы на несколько .xsd-файлов, но в некоторых файлах схемы есть один и тот же targetNamespace.Это действительно "разрешено"?

Пример (чрезвычайно упрощенный):

File    targetNamespace    Contents
------------------------------------------------------------
b1.xsd  uri:tempuri.org:b  complex type "fooType"
b2.xsd  uri:tempuri.org:b  simple type "barType"

a.xsd   uri:tempuri.org:a  imports b1.xsd and b2.xsd
                           definition of root element "foo", that
                           extends "b:fooType" with an attribute
                           of "b:barType"

(полное содержимое файла ниже.)

Тогда у меня естьXML-файл data.xml с таким содержимым:

<?xml version="1.0"?>
<foo bar="1" xmlns="uri:tempuri.org:a" xmlns:xs="http://www.w3.org/2001/XMLSchema" />

В течение длительного времени я считал, что все это правильно, поскольку Visual Studio, по-видимому, допускает этот стиль схемы.Однако сегодня я решил настроить утилиту командной строки для проверки XML-файлов и выбрал xmllint.

Когда я запускал xmllint --schema a.xsd data.xml, мне было выдано это предупреждение:

a.xsd: 4: импорт элемента: Предупреждение синтаксического анализатора схем: Элемент '{http://www.w3.org/2001/XMLSchema}import': Пропуск импорта схемы, расположенной в' b2.xsd 'для пространства имен' uri: tempuri.org: b ', посколькуэто пространство имен уже было импортировано со схемой, расположенной в 'b1.xsd'.

Тот факт, что импорт b2.xsd был пропущен, очевидно, приводит к этой ошибке:

a.xsd: 9: атрибут элемента: ошибка синтаксического анализатора схем: атрибут decl.'bar', атрибут 'type': значение QName '{uri: tempuri.org: b} barType' не преобразуется в (n) определение простого типа.

Если xmllintправильно, в опубликованных спецификациях, с которыми я работаю, будет ошибка. Есть? И Visual Studio будет не прав. Это так?

Я понимаю разницу между xs:import и xs:include.Сейчас я просто не понимаю, как xs:include может что-то исправить, поскольку:

  • b1.xsd и b2.xsd имеют одинаковые targetNamespace
  • они оба различаютсяв targetNamespace из a.xsd
  • и они не (должны) знать друг о друге

Является ли это недостатком в исходной спецификации схемы?Я начинаю думать, что третий пункт имеет решающее значение.Должен ли тот факт, что они не знают друг о друге, привести к началу размещения их в разных пространствах имен?


b1.xsd:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="uri:tempuri.org:b" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:complexType name="fooType" />
</xs:schema>

b2.xsd:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="uri:tempuri.org:b" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:simpleType name="barType">
    <xs:restriction base="xs:integer" />
  </xs:simpleType>
</xs:schema>

a.xsd:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="uri:tempuri.org:a" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:b="uri:tempuri.org:b">
  <xs:import namespace="uri:tempuri.org:b" schemaLocation="b1.xsd" />
  <xs:import namespace="uri:tempuri.org:b" schemaLocation="b2.xsd" />
  <xs:element name="foo">
    <xs:complexType>
      <xs:complexContent>
        <xs:extension base="b:fooType">
          <xs:attribute name="bar" type="b:barType" />
        </xs:extension>
      </xs:complexContent>
    </xs:complexType>
  </xs:element>
</xs:schema>

Примечания:

1) Я использую порт Windows libxml2 / xmllint , найденный по адресу www.zlatkovic.com .

1 Ответ

28 голосов
/ 15 февраля 2011

Суть проблемы в том, что это значит, когда у вас есть два разных элемента <import>, когда оба они ссылаются на одно и то же пространство имен.

Это помогает прояснить смысл, если учесть, что атрибут schemaLocation для <import> является полностью необязательным. Когда вы пропускаете это, вы просто говорите: «Я хочу импортировать схему пространства имен XYZ в эту схему». schemaLocation - это просто подсказка, где найти определение этой другой схемы.

Точное значение <import> немного нечетко, когда вы читаете спецификацию W3C, возможно, намеренно. В результате интерпретации различаются.

Некоторые процессоры XML допускают несколько <import> для одного и того же пространства имен и по существу объединяют все schemaLocation в одну цель.

Другие процессоры более строги и решают, что допустим только один <import> на целевое пространство имен. Я думаю, что это более правильно, если учесть, что schemaLocation является необязательным.

В дополнение к приведенным вами примерам VS и xmllint, Xerces-J также является суперстрогим и игнорирует последующие <import> для того же целевого пространства имен, что дает примерно ту же ошибку, что и xmllint. XML Spy, с другой стороны, гораздо более разрешительный (но тогда проверка XML Spy общеизвестно ненадежна)

Чтобы быть в безопасности, вы должны , а не иметь этот множественный импорт. В данном пространстве имен должен быть один «главный» документ, который, в свою очередь, имеет <include> для каждого вложенного документа. Этот мастер часто очень искусственный, действуя только как контейнер. для этих поддокументов.

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

Мех.

...