如何在不同范围内定义具有相同唯一名称属性的2个不同元素,并将其名称引用到属性

时间:2012-02-19 14:25:32

标签: xml xsd schema

<!--Metamodel (root element)-->
  <xsd:element name="Metamodel">
    <xsd:complexType>
      <xsd:choice minOccurs="0" maxOccurs="unbounded">
        <xsd:element ref="Package"/>
        <xsd:element ref="EnumerationLiteral"/>
        <xsd:element ref="Class"/>
        <xsd:element ref="Operation"/>
        <xsd:element ref="Parameter"/>
        <xsd:element ref="Property"/>
        <xsd:element ref="PrimitiveType"/>
        <xsd:element ref="Enumeration"/>
      </xsd:choice>
    </xsd:complexType>
  </xsd:element>
  <!--OBJECT-->
  <xsd:complexType name="Object"  abstract="true"/>
  <!--ELEMENT-->
  <xsd:complexType name="Element" abstract="true">
    <xsd:complexContent>
      <xsd:extension base="Object">
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>
  <!--NAMED ELEMENT-->
  <xsd:complexType name="NamedElement" abstract="true">
    <xsd:complexContent>
      <xsd:extension base="Element">
        <xsd:attribute name="Name" type="xsd:ID" use="optional"/>
        <xsd:attribute name="Description" type="lib:Description" use="optional"/>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>
  <!--TYPE-->
  <xsd:complexType name="Type" abstract="true">
    <xsd:complexContent>
      <xsd:extension base="NamedElement">
        <xsd:attribute name="Package" type="lib:Package" use="optional"/>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>
  <!--TYPED ELEMENT-->
  <xsd:complexType name="TypedElement" abstract="true">
    <xsd:complexContent>
      <xsd:extension base="NamedElement">
        <xsd:attribute name="Type" use="optional"/>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>
  <!--PACKAGE-->
  <xsd:element name="Package">
    <!--PACKAGE TYPE-->
    <xsd:complexType>
      <xsd:complexContent>
        <xsd:extension base="NamedElement">
          <xsd:all>
            <xsd:element ref="OwnedType" minOccurs="0"/>
            <xsd:element ref="NestedPackage" minOccurs="0"/>
          </xsd:all>
          <xsd:attribute name="NestingPackage" type="lib:NestingPackage"/>
          <xsd:attribute name="Uri" type="lib:Uri" use="optional"/>
        </xsd:extension>
      </xsd:complexContent>
    </xsd:complexType>
  </xsd:element>
  <!--ENUMERATIONAL LITERAL-->
  <xsd:element name="EnumerationLiteral" type="EnumerationLiteralType"/>
  <!--ENUMERATION LITERAL TYPE-->
  <xsd:complexType name="EnumerationLiteralType">
    <xsd:complexContent>
      <xsd:extension base="NamedElement">
        <xsd:attribute name="Enumeration" type="lib:Enumeration" use="optional"/>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>
  <!--CLASS-->
  <xsd:element name="Class" type="ClassType"/>
  <!--CLASS TYPE-->
  <xsd:complexType name="ClassType">
    <xsd:complexContent>
      <xsd:extension base="Type">
        <xsd:all>
          <xsd:element ref="OwnedOperation" minOccurs="0"/>
          <xsd:element ref="OwnedAttribute" minOccurs="0"/>
          <xsd:element ref="SuperClass" minOccurs="0"/>
        </xsd:all>
        <xsd:attribute name="IsAbstract" type="lib:IsAbstract"/>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>

我在Name元素上有NamedElement属性,此类型为ID。多数民众赞成,但我做不到:

<Metamodel>
  <Package Name="Serhat">
  </Package>
  <Class Name="Serhat"></Class>
</Metamodel>

我无法做到这一点,但我需要这样做。

我只需要一个Package Name="Serhat"Class可能有Nmae="Serhat"

另一个包中的另一个类可能有Name="Serhat",但此代码无法执行此操作。 我怎么能这样做呢?

2 个答案:

答案 0 :(得分:1)

xsd:ID表示全局唯一性约束。如果您想要一个非全局的唯一性约束,请尝试向包含元素添加xsd:uniqueMSDN example)标识约束,该元素可能是doc根元素。

<xsd:element name="Metamodel">
   ....
   <xs:unique name="uniquePackageNames">
     <xs:selector xpath="Package"/>
     <xs:field xpath="@Name"/>
   </xs:unique>
   <xs:unique name="uniqueClassNames">
     <xs:selector xpath="Class"/>
     <xs:field xpath="@Name"/>
     <xs:field xpath="@Package"/>
   </xs:unique>
</xsd:element>

编辑:添加了Class / @ Package字段,以便类名唯一性仅在包中。

答案 1 :(得分:0)

ID你是什么意思?你说

  

我在NamedElement元素上有Name属性,这个类型是ID

但是你的代码中有

<xsd:attribute name="Name" type="lib:Name" use="optional"/>

lib:Name定义为xsd:ID

xsd:ID的含义是您不能在同一文档中拥有具有此类ID的其他元素或名称。如果您想要更复杂的方法来定义哪些ID可能以及如何混合,则必须使用xsd:NCName作为Name属性的类型和其他Schematron rules

Schematron用于表示无法在XML Schema中表达的规则,在您的情况下,表示不同的Package必须具有不同的Name属性,但Class es位于不同的{ {1}}可以使用相同的名称。