是否可以仅在另一个元素的属性设置为特定值时才定义XML元素的属性?

时间:2014-07-31 19:58:03

标签: xml xsd xsd-validation

我想问一下这是否可行,如果是的话,如何实现它:

例如,如果我在XML模式定义中有一个带有complexType的元素定义,如下所示:

<xsd:element name="tag" type="tag"/>
<xs:complexType name="tag">
    <xs:choice maxOccurs="unbounded">
        <xs:element name="subtag" type="subtag"/>
        <xs:element name="another_subtag" type="another_subtag"/>
        <xs:element name="another_subtag_2" type="another_subtag_2"/>
    </xs:choice>
    <xs:attribute name="type" type="attr_type"/>
    <xs:attribute name="an_attr" type="an_attr"/>
    <xs:attribute name="another_attr" type="another_attr"/>
</xs:complexType name="attr_type">
    <xsd:restriction base="xsd:string">
         <xsd:enumeration value="type_1"/>
         <xsd:enumeration value="type_2"/>
         <xsd:enumeration value="type_3"/>
    </xsd:restriction>
<xsd:simpleType/>

1)如果标签元素的属性'attr_type'设置为'type_2',是否可以使标签元素的属性' an_attr '仅

另一个问题: 2)是否可以使complexType'标签'再次包含不同的子元素,例如关于'attr_type'的价值?例如:

<tag attr_type="type_1">

只有这个孩子:

<xs:element name="subtag" type="subtag"/>

并且:

<tag attr_type="type_2">

只有孩子:

 <xs:element name="another_subtag" type="another_subtag"/>
OR
 <xs:element name="another_subtag_2" type="another_subtag_2"/>

如果有可能,我该如何实现?

感谢您的关注!

编辑:正如我在这里看到的那样 - &gt; https://blogs.oracle.com/rammenon/entry/xml_schema_11_what_you_need_to 在示例编号22中(在条件类型分配中),是否可以这样做?

<!--inline alternative type definitions --> 
<element name="TimeTravel" type="TravelType"> 
      <alternative test="@direction='Future'"> 
          <complexType> 
              <complexContent> 
              <restriction base="TravelType" 
                         .... 
<!--        some past travel related elements go here --> 
            </complexType> 
       </alternative> 
      <alternative test="@direction='Past'"> 
          <complexType> 
              <complexContent> 
              <restriction base="TravelType" 
                         .... 
   <!--        some future travel related elements go here --> 
            </complexType> 
       </alternative> 
  </element> 
                          OR 
<!--Named alternative type definitions --> 
<element name="TimeTravel" type="TravelType"> 
   <alternative test="@direction='Future' type="FutureTravelType"/> 
   <alternative test="@direction='Past' type="PastTravelType"/> 
</element>

据我所知,TimeTravel元素可以根据方向属性值使用不同的complexType,我是否正确?但它说必须使用XSD 1.1。我可以在XML Schema中使用此规则吗?

3 个答案:

答案 0 :(得分:2)

在XSD 1.1中可以使用“条件类型赋值”的新功能。这允许您将元素的类型定义为其属性值的函数。

XSD 1.1在Altova,Saxon和Xerces中实现。

答案 1 :(得分:2)

不,因为条件类型赋值(在另一个答案中提到)只为元素指定一个类型。因此,名称,条件类型赋值。此外,当使用条件类型赋值时,元素的类型由其自己的属性确定,而不是由某些其他元素的属性确定。

即使使用带条件类型赋值的XPATH表达式,您也只能访问要验证的元素的属性。它无法访问其父级或祖先,甚至无法像断言一样访问其子级或后代。

[编辑]主要问题,如发布,询问是否可以根据其他元素的属性要求第一个属性,答案是否定的。

这需要比XML Schema 1.1更高级别的验证。也许Schematron ???我不知道。有时候答案并不是你想要听到的。

参考:Priscilla Walmsley的最终XML模式,第2版,第378-379页。

以下是a great post,总结了无数次这样的问题,有关XML验证的问题。 Schema 1.1中的新增内容范围非常有限。

答案 2 :(得分:2)

让我们再试一次,因为我的答案一直存在争议,最好再详细说明一下。编辑我的原始答案会使随后的评论难以理解,只会增加混乱。

问题1:是否可以制作属性&#39; an_attr&#39;仅当tag元素具有属性&#39; attr_type&#39;时才需要标记元素设置为&#39; type_2&#39;?

答案1:是的。您可以这样做(测试;从原始修改以避免引用不相关和未定义的类型):

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="tag" type="tagType">
      <xs:alternative test="@attr_type='type_2'" type="tagTypeWithMandatoryAttr"/>
    </xs:element>

    <xs:complexType name="tagType">
        <xs:choice maxOccurs="unbounded">
            <xs:element name="subtag" type="xs:anyType"/>
            <xs:element name="another_subtag" type="xs:anyType"/>
            <xs:element name="another_subtag_2" type="xs:anyType"/>
        </xs:choice>
        <xs:attribute name="type" type="xs:string"/>
        <xs:attribute name="an_attr" type="xs:string"/>
        <xs:attribute name="another_attr" type="xs:string"/>
    </xs:complexType>

    <xs:complexType name="tagTypeWithMandatoryAttr">
     <xs:complexContent>
      <xs:restriction base="tagType">
          <xs:choice maxOccurs="unbounded">
            <xs:element name="subtag" type="xs:anyType"/>
            <xs:element name="another_subtag" type="xs:anyType"/>
            <xs:element name="another_subtag_2" type="xs:anyType"/>
          </xs:choice>
          <xs:attribute name="type" type="xs:string"/>
          <xs:attribute name="an_attr" type="xs:string" use="required"/>
          <xs:attribute name="another_attr" type="xs:string"/>
      </xs:restriction>
     </xs:complexContent>
    </xs:complexType>
</xs:schema>

问题2:

是否可以制作complexType&#39;标签&#39;包含不同的子元素,例如关于&#39; attr_type&#39;?

的价值

答案2:

是的,例如(经过类似测试):

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="tag" type="xs:anyType">
      <xs:alternative test="@attr_type='type_2'" type="tagType1"/>
      <xs:alternative type="tagType2"/>
    </xs:element>

    <xs:complexType name="tagType1">
        <xs:choice maxOccurs="unbounded">
            <xs:element name="subtag" type="xs:anyType"/>
            <xs:element name="another_subtag" type="xs:anyType"/>
            <xs:element name="another_subtag_2" type="xs:anyType"/>
        </xs:choice> 
    </xs:complexType>

    <xs:complexType name="tagType2">
        <xs:choice maxOccurs="unbounded">
            <xs:element name="subtag" type="xs:anyType"/>
            <xs:element name="another_subtag" type="xs:anyType"/>
            <xs:element name="another_subtag_2" type="xs:anyType"/>
        </xs:choice> 
    </xs:complexType>
</xs:schema>

问题0:是否可以仅在另一个元素(F)的属性设置为特定值时才定义XML元素(E)的属性?

答案0:它取决于两个元素E和F的关系。如果F是E的祖先,则可以在F的声明中使用条件类型赋值来完成。如果E和F是兄弟姐妹或更多远程相关,然后使用条件类型赋值无法完成,但可以使用附加到E和F的共同祖先的断言来完成。