代码之家  ›  专栏  ›  技术社区  ›  Klaim

XSD:如何在子元素类型中设置属性值?

  •  0
  • Klaim  · 技术社区  · 14 年前

    在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++ code generator 似乎不同意:

    错误:属性“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 回复  |  直到 14 年前
        1
  •  2
  •   outis    14 年前

    若要派生类型并固定值,请使用 restriction :

    <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>
    

    从阅读规范来看,我本以为你 couldn't add attributes in a restriction 除非基类型有 attribute wildcard ,但W3CXSD验证器接受上述内容。如果遇到问题,可以将定义分解为限制和扩展:

    <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>
    

    另一个解决方法是添加 attribute wildcard 到基类型。

    <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>
    

    这不是等效的解决方案,因为它允许事件具有属性的任何内容(一般来说,这可能是不需要的,但可能不用于代码生成),并且它不添加其他类型(这是可取的)。

    请注意,基中的任何粒子(元素、组或通配符)必须 repeated in the restriction ,否则元素中不允许使用它们。如果在基上需要受限属性,则在限制中也必须需要它。限制必须满足许多其他属性才能有效 derivation particle . 规格说明不太可读,但您通常可以通过它来绊倒。

    另请参见:“ how to use restrictions and extensions in XSD simultanously “。