XSD: как установить значения атрибутов в типе дочернего элемента? - PullRequest
0 голосов
/ 17 ноября 2010

В файле xsd у меня есть этот базовый тип элемента:

<xs:complexType name="event" abstract="true" >
    <xs:attribute name="move" type="aos:move_ref" use="required" />
    <xs:attribute name="type" type="aos:event_type" use="required" />
</xs:complexType>

И я хочу определить значение атрибута type в дочерних типах, поэтому я попробовал это:

<xs:complexType name="signal" >
    <xs:complexContent>
      <xs:extension base="aos:event">
        <xs:attribute name="type" type="aos:event_type" fixed="signal" />
        <xs:attribute name="source" type="aos:signal_source" use="required" />
      </xs:extension>
    </xs:complexContent>
 </xs:complexType>

Кажется, Visual Studio не беспокоит, но Генератор кода CodeSynthesis C ++ , похоже, не согласен:

ошибка: атрибут type уже определено в базе

Как мне написать это? Я просто хочу, чтобы значение атрибута type было специфичным для каждого другого дочернего типа.

редактировать ----

Чтобы прояснить вопрос, я напишу то же самое, что хочу сделать, но на C ++.

Вот базовый класс:

class Event
{
public:

   std::string name() const { return m_name; }

protected:

   // we need the child class to set the name
   Event( const std::string& name ) : m_name( name ) {} 

   // it's a base class
   virtual ~Event(){}

private:

   std::string m_name;

};

Теперь один из потомков может быть реализован так:

class Signal : public Event
{
public:

   Signal() : Event( "signal" ){}

};

Как видите, дочерний класс определяет значения атрибутов, которые определены базовым классом. Можно ли даже выразить в xsd?

1 Ответ

2 голосов
/ 21 ноября 2010

Чтобы получить тип и исправить значение, используйте ограничение :

<xs:complexType name="signal" >
    <xs:complexContent>
      <xs:restriction base="aos:event">
        <xs:attribute name="type" type="aos:event_type" fixed="signal" use="required" />
        <xs:attribute name="source" type="aos:signal_source" use="required" />
      </xs:restriction>
    </xs:complexContent>
 </xs:complexType>

Из прочтения спецификации я бы ожидал, что вы не сможете добавить атрибутыв ограничении , если только базовый тип не имеет подстановочного знака атрибута , но валидатор W3C XSD принимает вышеуказанное.Если вы столкнетесь с проблемами, вы можете разбить определение на ограничение и расширение:

<xs:complexType name="fixedSignalEvent">
  <xs:complexContent>
    <xs:restriction base="aos:event">
      <xs:attribute name="type" type="aos:event_type" fixed="signal" use="required" />
    </xs:restriction>
  </xs:complexContent>
</xs:complexType>

<xs:complexType name="signal" >
  <xs:complexContent>
    <xs:extension base="aos:fixedSignalEvent">
      <xs:attribute name="source" type="aos:signal_source" use="required" />
    </xs:extension>
  </xs:complexContent>
</xs:complexType>

Другим исправлением будет добавление подстановочного знака атрибута к базовому типу.

<xs:complexType name="event" abstract="true" >
    <xs:attribute name="move" type="aos:move_ref" use="required" />
    <xs:attribute name="type" type="aos:event_type" use="required" />
    <xs:anyAttribute />
</xs:complexType>

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

Обратите внимание, что любые частицы (элементы, группы или символы подстановки) в базе должны повторяться в ограничении , иначе они не будут разрешены вэлемент.Если для базы требуется ограниченный атрибут, он также должен быть указан в ограничении.Существует множество других свойств, которым должно соответствовать ограничение, чтобы быть действительным производным или частицей .Спецификация не очень удобочитаема, но вы можете наткнуться на нее.

См. Также: " как использовать ограничения и расширения в XSD одновременно ".

...