是否可能只在将另一个元素的属性设置为特定值时才需要XML元素的属性?

时间:2022-11-19 10:03:33

I would like to ask if this is possible and if yes, how to achieve it:

我想问,这是否可能,如果可能,如何实现:

For example if I have an element definition with a complexType in an XML schema definition like this:

例如,如果我在XML模式定义中有一个具有复杂类型的元素定义,如下所示:

<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) Is it possible to make the attribute 'an_attr' of the tag element required only if the tag element has the attribute 'attr_type' set to 'type_2'?

1)是否只有当标记元素的属性'attr_type'设置为'type_2'时,才需要标记元素的属性'an_attr' ?

And another question: 2) Is it possible to make the complexType 'tag' contain different child elements based again e.g. on the value of the 'attr_type'? For example for:

另一个问题是:2)是否可能使complexType '标签'包含基于'attr_type'的不同的子元素?例如:

<tag attr_type="type_1">

have only this childs:

只有这个孩子:

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

And for:

和:

<tag attr_type="type_2">

have only childs:

只有孩子:

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

?

吗?

If it is possible, how can I achieve this?

如果可能的话,我该如何做到这一点呢?

Thanks for the attention!

谢谢你的关注!

EDIT: As I saw here -> https://blogs.oracle.com/rammenon/entry/xml_schema_11_what_you_need_to In the example number 22 (in Conditional Type Assignments), could it be done in such a way?

编辑:正如我在这里看到的——> 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>

As I understood it, TimeTravel element can have different complexTypes based on the direction attribute value, am I correct? But it says that XSD 1.1 must be used. Can I use this rules inside my XML Schema?

根据我的理解,TimeTravel元素可以根据方向属性值拥有不同的complextype,对吗?但是它说必须使用XSD 1.1。我可以在XML模式中使用这些规则吗?

3 个解决方案

#1


2  

Let's try again, since my answer has been disputed, it's probably best to give it again in more detail. Editing my original answer would make the subsequent comments incomprehensible and only add confusion.

让我们再试一次,因为我的答案有争议,所以最好再详细一点。编辑我最初的答案会使后面的评论变得难以理解,只会增加混乱。

Question 1: Is it possible to make the attribute 'an_attr' of the tag element required only if the tag element has the attribute 'attr_type' set to 'type_2'?

问题1:如果标记元素的属性'attr_type'设置为'type_2',那么是否可能只需要标记元素的属性'an_attr' ?

Answer 1: yes. You can do it like this (tested; modified from the original to avoid reference to irrelevant and undefined types):

答:是的。你可以这样做(测试;从原来的修改,避免引用无关的和未定义的类型):

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

Question 2:

问题2:

Is it possible to make the complexType 'tag' contain different child elements based again e.g. on the value of the 'attr_type'?

是否有可能使复杂类型'tag'包含基于'attr_type'的不同子元素?

Answer 2:

答案2:

Yes, for example (similarly tested):

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

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

Question 0: Is it possible to define an attribute of an XML element (E) to be required only if another element (F)'s attribute is set to a particular value?

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

Answer 0: it depends on the relationship of the two elements E and F. If F is an ancestor of E, then it can be done using conditional type assignment in the declaration of F. If E and F are siblings or more remotely related, then it cannot be done using conditional type assignment, but it can be done using an assertion attached to the common ancestor of E and F.

回答0:这取决于两个元素的关系E和F .如果F是E的祖先,那么它可以通过使用声明的条件类型分配F .如果E和F是兄弟姐妹或多个远程相关的,那么它不能使用条件类型分配,但它可以通过使用断言E和F的共同祖先。

#2


2  

It's possible in XSD 1.1 using the new feature of "conditional type assignment". This allows you to define the type of an element as a function of the values of its attributes.

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

XSD 1.1 is implemented in Altova, Saxon, and Xerces.

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

#3


2  

No, because conditional type assignment (mentioned in the other answer) only assigns a type to an element. Hence the name, conditional type assignment. Furthermore, when using conditional type assignment the element's type is determined by its own attributes and not the attributes of some other element.

不,因为条件类型赋值(在另一个答案中提到)只向元素分配类型。因此命名为条件类型赋值。此外,在使用条件类型赋值时,元素的类型由它自己的属性决定,而不是由其他元素的属性决定。

Even using an XPATH expression with conditional type assignment, you can only access the attributes of the element being validated. It cannot access its parent or ancestors, and it cannot even access its children or descendants like assertions can.

即使使用带有条件类型赋值的XPATH表达式,您也只能访问正在验证的元素的属性。它不能访问它的父类或祖先,甚至不能像断言那样访问它的子女或后代。

[EDIT] The main question, as posted, asked if the 1st attribute can be required based on another element's attribute's, the answer to that is no.

[编辑]主要的问题,如所贴,问是否可以根据另一个元素的属性要求第一个属性,答案是否定的。

This would required a much higher level of validation than can be done with XML Schema 1.1. Maybe Schematron ??? I don't know. Sometimes the answer isn't what you want to hear.

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

Reference: Definitive XML Schema by Priscilla Walmsley, 2nd edition, page 378-379.

参考:Priscilla Walmsley的权威XML模式,第二版,第378-379页。

Here is a great post that sums up the countless times questions like this have been asked about XML validation. The new additions in Schema 1.1 are very limited in scope.

下面是一篇很好的文章,总结了关于XML验证的无数问题。模式1.1中的新增内容在范围上非常有限。

#1


2  

Let's try again, since my answer has been disputed, it's probably best to give it again in more detail. Editing my original answer would make the subsequent comments incomprehensible and only add confusion.

让我们再试一次,因为我的答案有争议,所以最好再详细一点。编辑我最初的答案会使后面的评论变得难以理解,只会增加混乱。

Question 1: Is it possible to make the attribute 'an_attr' of the tag element required only if the tag element has the attribute 'attr_type' set to 'type_2'?

问题1:如果标记元素的属性'attr_type'设置为'type_2',那么是否可能只需要标记元素的属性'an_attr' ?

Answer 1: yes. You can do it like this (tested; modified from the original to avoid reference to irrelevant and undefined types):

答:是的。你可以这样做(测试;从原来的修改,避免引用无关的和未定义的类型):

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

Question 2:

问题2:

Is it possible to make the complexType 'tag' contain different child elements based again e.g. on the value of the 'attr_type'?

是否有可能使复杂类型'tag'包含基于'attr_type'的不同子元素?

Answer 2:

答案2:

Yes, for example (similarly tested):

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

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

Question 0: Is it possible to define an attribute of an XML element (E) to be required only if another element (F)'s attribute is set to a particular value?

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

Answer 0: it depends on the relationship of the two elements E and F. If F is an ancestor of E, then it can be done using conditional type assignment in the declaration of F. If E and F are siblings or more remotely related, then it cannot be done using conditional type assignment, but it can be done using an assertion attached to the common ancestor of E and F.

回答0:这取决于两个元素的关系E和F .如果F是E的祖先,那么它可以通过使用声明的条件类型分配F .如果E和F是兄弟姐妹或多个远程相关的,那么它不能使用条件类型分配,但它可以通过使用断言E和F的共同祖先。

#2


2  

It's possible in XSD 1.1 using the new feature of "conditional type assignment". This allows you to define the type of an element as a function of the values of its attributes.

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

XSD 1.1 is implemented in Altova, Saxon, and Xerces.

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

#3


2  

No, because conditional type assignment (mentioned in the other answer) only assigns a type to an element. Hence the name, conditional type assignment. Furthermore, when using conditional type assignment the element's type is determined by its own attributes and not the attributes of some other element.

不,因为条件类型赋值(在另一个答案中提到)只向元素分配类型。因此命名为条件类型赋值。此外,在使用条件类型赋值时,元素的类型由它自己的属性决定,而不是由其他元素的属性决定。

Even using an XPATH expression with conditional type assignment, you can only access the attributes of the element being validated. It cannot access its parent or ancestors, and it cannot even access its children or descendants like assertions can.

即使使用带有条件类型赋值的XPATH表达式,您也只能访问正在验证的元素的属性。它不能访问它的父类或祖先,甚至不能像断言那样访问它的子女或后代。

[EDIT] The main question, as posted, asked if the 1st attribute can be required based on another element's attribute's, the answer to that is no.

[编辑]主要的问题,如所贴,问是否可以根据另一个元素的属性要求第一个属性,答案是否定的。

This would required a much higher level of validation than can be done with XML Schema 1.1. Maybe Schematron ??? I don't know. Sometimes the answer isn't what you want to hear.

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

Reference: Definitive XML Schema by Priscilla Walmsley, 2nd edition, page 378-379.

参考:Priscilla Walmsley的权威XML模式,第二版,第378-379页。

Here is a great post that sums up the countless times questions like this have been asked about XML validation. The new additions in Schema 1.1 are very limited in scope.

下面是一篇很好的文章,总结了关于XML验证的无数问题。模式1.1中的新增内容在范围上非常有限。