XML Schema - 依赖于可选属性存在的子元素

时间:2021-03-13 17:18:19

Is it possible to define in XSD the following scenario:

是否可以在XSD中定义以下场景:

  1. Parent element has an attribute that

    父元素具有一个属性

    is optional.

    是可选的。

  2. If the attribute is not

    如果属性不是

    present in XML, at least one child
    
    element must exists.
    
  3. If the

    如果

    attribute is present, there can be
    
    zero or more child elements.
    

Example:

例:

VALID

有效

<parent externel-source="some_name" />



<parent externel-source="some_name">

  <child>some value</child>

</parent>



<parent>

  <child> some value</child>

</parent>

NOT VALID

无效

<parent />

4 个解决方案

#1


-2  

No i think not.

不,我想不。

#2


3  

No .. the reason is : In your case you are trying to validate the presence of an element/tag depending on the value of some other tag/attribute .. (XSD is basically a set of declaration) which requires multiple declaration of a same element ..
Multiple declaration of a same element isn't allowed in XSD .. :-(
Check out the similar problem (click here) posted by a * member

不..原因是:在你的情况下,你试图验证元素/标签的存在,取决于一些其他标签/属性的值..(XSD基本上是一组声明),需要多个声明同一个在XSD中不允许多个相同元素的声明.. :(看看*成员发布的类似问题(点击这里)

#3


0  

Sorry to resurrect this message, but I thought I could add a bit on the "why" of things. W3C XML Schema requires all of its sequences to be fully deterministic. For performance/simplicity reasons, it is not designed to look ahead or look back, only works on the current element. Also I believe this is inherited from SGML.

抱歉复活了这条消息,但我想我可以补充一下“为什么”的事情。 W3C XML Schema要求其所有序列都是完全确定的。出于性能/简单的原因,它不是设计为向前看或向后看,只适用于当前元素。另外我相信这是继承自SGML。

What you want to do requires such functionality. You might want to look at Schematron; it supports what you want.

您想要做的事情需要这样的功能。你可能想看一下Schematron;它支持你想要的东西。

#4


0  

Yes, most definitely you can, using xsi:type (which is probably not what you want!). Eg with the xsd below;

是的,绝对可以,使用xsi:type(可能不是你想要的!)。例如,下面的xsd;

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xs:element name="data">
    <xs:complexType>
        <xs:choice>
            <xs:element ref="elemParent" minOccurs="1"  maxOccurs="unbounded"/> 
        </xs:choice>
    </xs:complexType>
</xs:element>
<xs:element name="elemParent" type="ctBase"></xs:element>
<xs:complexType name="ctNoAttChildReq">
    <xs:complexContent>
        <xs:extension base="ctBase">
            <xs:sequence>
                <xs:element name="elemKid" type="xs:string"></xs:element>
                <xs:element name="elemKidAdditional" type="xs:string" minOccurs="0"></xs:element>
            </xs:sequence>              
        </xs:extension>
    </xs:complexContent>    
</xs:complexType>
<xs:complexType name="ctAttNoChild">
    <xs:complexContent>
        <xs:extension base="ctBase">
            <xs:attribute name="attReq" use="required"/>
        </xs:extension>
    </xs:complexContent>        
</xs:complexType>       
<xs:complexType name="ctBase" abstract="true">
    <xs:sequence/>
</xs:complexType>       

you get an instance that has either an attribute or one or more kids but you have to have xsi:type in the instance which may or may not be a show-stopper.

你得到一个具有属性或一个或多个孩子的实例,但你必须在实例中有xsi:type,这可能是也可能不是show-stopper。

<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="file:///C:/Xsds/*_2070316_WIP.xsd">
<elemParent  attReq="Yo!" xsi:type="ctAttNoChild"/>
<elemParent xsi:type="ctNoAttChildReq">
    <elemKid>Adam</elemKid>
</elemParent>
<elemParent xsi:type="ctNoAttChildReq">
    <elemKid>Eve</elemKid>
    <elemKidAdditional>Sid</elemKidAdditional>
</elemParent>   

#1


-2  

No i think not.

不,我想不。

#2


3  

No .. the reason is : In your case you are trying to validate the presence of an element/tag depending on the value of some other tag/attribute .. (XSD is basically a set of declaration) which requires multiple declaration of a same element ..
Multiple declaration of a same element isn't allowed in XSD .. :-(
Check out the similar problem (click here) posted by a * member

不..原因是:在你的情况下,你试图验证元素/标签的存在,取决于一些其他标签/属性的值..(XSD基本上是一组声明),需要多个声明同一个在XSD中不允许多个相同元素的声明.. :(看看*成员发布的类似问题(点击这里)

#3


0  

Sorry to resurrect this message, but I thought I could add a bit on the "why" of things. W3C XML Schema requires all of its sequences to be fully deterministic. For performance/simplicity reasons, it is not designed to look ahead or look back, only works on the current element. Also I believe this is inherited from SGML.

抱歉复活了这条消息,但我想我可以补充一下“为什么”的事情。 W3C XML Schema要求其所有序列都是完全确定的。出于性能/简单的原因,它不是设计为向前看或向后看,只适用于当前元素。另外我相信这是继承自SGML。

What you want to do requires such functionality. You might want to look at Schematron; it supports what you want.

您想要做的事情需要这样的功能。你可能想看一下Schematron;它支持你想要的东西。

#4


0  

Yes, most definitely you can, using xsi:type (which is probably not what you want!). Eg with the xsd below;

是的,绝对可以,使用xsi:type(可能不是你想要的!)。例如,下面的xsd;

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xs:element name="data">
    <xs:complexType>
        <xs:choice>
            <xs:element ref="elemParent" minOccurs="1"  maxOccurs="unbounded"/> 
        </xs:choice>
    </xs:complexType>
</xs:element>
<xs:element name="elemParent" type="ctBase"></xs:element>
<xs:complexType name="ctNoAttChildReq">
    <xs:complexContent>
        <xs:extension base="ctBase">
            <xs:sequence>
                <xs:element name="elemKid" type="xs:string"></xs:element>
                <xs:element name="elemKidAdditional" type="xs:string" minOccurs="0"></xs:element>
            </xs:sequence>              
        </xs:extension>
    </xs:complexContent>    
</xs:complexType>
<xs:complexType name="ctAttNoChild">
    <xs:complexContent>
        <xs:extension base="ctBase">
            <xs:attribute name="attReq" use="required"/>
        </xs:extension>
    </xs:complexContent>        
</xs:complexType>       
<xs:complexType name="ctBase" abstract="true">
    <xs:sequence/>
</xs:complexType>       

you get an instance that has either an attribute or one or more kids but you have to have xsi:type in the instance which may or may not be a show-stopper.

你得到一个具有属性或一个或多个孩子的实例,但你必须在实例中有xsi:type,这可能是也可能不是show-stopper。

<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="file:///C:/Xsds/*_2070316_WIP.xsd">
<elemParent  attReq="Yo!" xsi:type="ctAttNoChild"/>
<elemParent xsi:type="ctNoAttChildReq">
    <elemKid>Adam</elemKid>
</elemParent>
<elemParent xsi:type="ctNoAttChildReq">
    <elemKid>Eve</elemKid>
    <elemKidAdditional>Sid</elemKidAdditional>
</elemParent>