【问题标题】:XSD : How to set attributes values in children element type?XSD:如何在子元素类型中设置属性值?
【发布时间】:2010-11-16 21:29:52
【问题描述】:

在一个 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 似乎不同意:

错误:属性“类型”已经存在 在base中定义

我该怎么写?我只希望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表达吗?

【问题讨论】:

  • 你能给我们一个示例 XML 吗?
  • 真的有必要吗?我可以,但我不明白它有什么帮助。你想要某种用例吗?
  • 不,我只是想澄清一下,不清楚你的声明像I just want the value of the type attribute to be specific to each different child type,如果你想在同一个子/实体下定义一个属性不同那么它不是可能,如果您想为不同的实体/子项以不同的方式定义相同的属性,那么很有可能。
  • 我希望相同的属性具有由子类型定义的不同值。如果实在没有办法给在基类型中定义的属性设置值,而不能在子类型中设置,那么请回答一下?
  • 其实在xml中,这点不会很明显。只有当您尝试从不同的元素类型中获取“类型”属性时,它才会很明显,例如这里的 。也许这最终没有用,我在问自己是否可以通过其他方式获得信息。

标签: c++ xsd xsd.exe codesynthesis


【解决方案1】:

要派生类型并修复值,请使用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,但 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>

另一个解决方法是将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,否则将不允许它们出现在元素中。如果在基础上需要限制属性,则限制中也必须要求它。限制必须满足许多其他属性才能成为有效的derivationparticle。该规范不是那么可读,但您通常可以偶然发现它。

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

【讨论】:

  • 看来这个解析器仍然不喜欢我重复声明属性的事实,即使使用限制扩展(使用一个简单的子类型,它只尝试设置 this 的值属性)......太糟糕了:/
  • 等等,我做错了,它似乎有效!我没有尝试解析正确的文件,抱歉!我将不得不做更多的检查,并为更复杂的儿童课程做这个把戏。
  • 好吧,对于复杂的子项(扩展类型),我找不到如何“将定义分解为限制和扩展”。我可以在相同的复杂类型中执行此操作吗?可以举个例子吗?
  • 附加示例是否说明了问题?请注意,您不能在扩展中嵌套限制(反之亦然),因此您需要两个单独的复杂类型。
  • 是的,这很清楚。这就是我的猜测,但希望他们是一种更直观的方式。分离是他们唯一设置值,这不是好的设计......但如果这是唯一的方法,那么我会这样做。谢谢!
猜你喜欢
  • 2016-11-16
  • 1970-01-01
  • 2015-01-09
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
  • 2013-10-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多