7

Is it possible to define in XSD the following scenario:

  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 />
Mike Morearty
  • 9,953
  • 5
  • 31
  • 35
Aoi Karasu
  • 3,730
  • 3
  • 37
  • 61

4 Answers4

4

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

Community
  • 1
  • 1
Rookie Programmer Aravind
  • 11,952
  • 23
  • 81
  • 114
1

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.

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

Selim
  • 1,013
  • 9
  • 15
0

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

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

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

walbury
  • 68
  • 5
-4

No i think not.

particle
  • 3,280
  • 4
  • 27
  • 39
  • Answers of such type are not satisfactory for me. What is the reasoning behind your statement? – Aoi Karasu Jan 15 '10 at 11:00
  • 2
    XML schema types are very similar to you OO programming types. You can create a complex type and you can restrict order of elements type of element and attribute and restriction on what kind of values can be assigned. That is all xsd can do for you. What you want is something of constraint that span more than one element/attribute which is simply not possible with xsd. you have to write your own code to valid this. – particle Jan 15 '10 at 14:51
  • I also think it is not possible, and that saying that is a pretty good answer (if it's correct) :-) – Yossi Dahan Jan 15 '10 at 15:21
  • Thank you very much for your comment. Now I get the picture :) – Aoi Karasu Jan 18 '10 at 08:36