Ограничить элемент типа в другом пространстве имен

Я думаю, что мне нужно сделать это не возможно с XSD 1.0, но в любом случае я спрошу... У меня есть complexType в файле скажем a.xsd, В принципе я не могу коснуться этого файла. В частности, я не могу изменить его targetNamespace, Примером может быть:

<xs:schema targetNamespace="http://myns.original" 
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:orig="http://myns.original">

  <xs:element name="config" type="orig:ConfigType"/>

  <xs:complexType name="ConfigType">
    <xs:sequence>
      <xs:element name="fieldA" type="xs:integer" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>

</xs:schema>

У меня есть второй файл, b.xsdгде я расширяю тип, определенный в a.xsdи переопределить элемент, ранее определенный в a.xsd, используя substitutionGroup, Пока все в порядке, и следующий пример выглядит нормально:

<xs:schema targetNamespace="http://myns.myns" 
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:myns="http://myns.myns" xmlns:orig="http://myns.original">

  <xs:import namespace="http://myns.original" schemaLocation="a.xsd"/>

  <xs:complexType name="ConfigType">
    <xs:complexContent>
      <xs:extension base="orig:ConfigType">
        <xs:sequence>
          <xs:element name="fieldB" type="xs:string"/>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:element name="config" type="myns:ConfigType" substitutionGroup="orig:config"/>

</xs:schema>

Проблемы идут: одно поле в оригинале complexType необязательно (minOccurs=0). Теперь мне нужно переопределить этот тип, чтобы это поле было обязательным (minOccurs=1). Я догадался, что это может быть достигнуто с xsd:redefineпоэтому я попробовал следующее:

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

  <xs:redefine schemaLocation="b.xsd">

    <xs:complexType name="ConfigType">
      <xs:complexContent>
        <xs:restriction base="myns:ConfigType">
          <xs:sequence>
            <xs:element name="fieldA" minOccurs="1"/>
          </xs:sequence>
        </xs:restriction>
      </xs:complexContent>
    </xs:complexType>

  </xs:redefine>

</xs:schema>

Но я получаю следующие сообщения:

 There is not a complete functional mapping between the particles.
 Error for type 'ConfigType'.  The particle of the type is not a valid restriction of the particle of the base.

Честно говоря, я не совсем понимаю эти сообщения, но после некоторого исследования кажется, что реальная проблема заключается в том, что переопределенные поля должны принадлежать тому же пространству имен, что и переопределение. В моем случае я стараюсь ограничить поле orig:fieldAв пространстве имен http://myns.original, в файле с targetNamespace="http://myns.myns". Конечно, если продолжать расширять тип в c.xsd как я сделал в b.xsdНет проблем, так как я не пытаюсь изменить что-либо из другого пространства имен.

Кто-нибудь знает, можно ли этого достичь? Одним из решений является репликация определений, которые будут изменены в другом файле, a_2.xsdс правом targetNamespace, Но это крайне нежелательное и не поддерживаемое решение для сложной системы.

1 ответ

Решение

Единственная проблема, которую я вижу до сих пор, заключается в том, что в схеме a.xsd вы определили:

<xs:element name="fieldA" type="xs:integer" minOccurs="0"/>

тогда как в последней схеме (переопределении) вы имеете:

<xs:element name="fieldA" minOccurs="1"/>

Последнее объявление фактически означает, что вы неявно указываете xs:anyType для fieldA:

<xs:element name="fieldA" type="xs:anyType" minOccurs="1"/>

Помните, что когда вы выводите новый тип по ограничению (что на самом деле вы делаете в переопределении), вы должны полностью определить модель содержимого элемента. Но эта новая модель контента должна полностью соответствовать старой.

Это не так в вашей последней схеме, потому что ранее согласно a.xsd, элемент fieldA было разрешено иметь только целочисленное значение. Но теперь вы говорите, что может принять все, что угодно. Это, безусловно, вызовет ошибку, и сообщение, которое вы получили (хотя на самом деле довольно бессмысленно):

Частица типа не является допустимым ограничением частицы основания.

кажется, говорит именно об этом.

Другие вопросы по тегам