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

时间:2010-01-15 08:36:32

标签: xml validation xsd

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

  1. 父元素的属性为

    是可选的。

  2. 如果属性不是

    present in XML, at least one child
    
    element must exists.
    
  3. 如果

    attribute is present, there can be
    
    zero or more child elements.
    
  4. 示例:

    VALID

    <parent externel-source="some_name" />
    
    
    
    <parent externel-source="some_name">
    
      <child>some value</child>
    
    </parent>
    
    
    
    <parent>
    
      <child> some value</child>
    
    </parent>
    

    无效

    <parent />
    

4 个答案:

答案 0 :(得分:3)

否..原因是:在您的情况下,您尝试根据某些其他标记/属性的值来验证元素/标记的存在。(XSD基本上是一组声明),需要多个声明相同的元素..
XSD中不允许多个相同元素的声明.. :-(
查看stackOverFlow成员发布的similar problem (click here)

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

是的,绝对可以,使用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>       

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

<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="file:///C:/Xsds/StackOverflow_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>   

答案 3 :(得分:-2)

不,我不这么认为。