Question

I want to validate data as in below array:

input_array = array(
  "boy"=> array("boy_id"=>1),
   "first_name=>"First Name",
   "last_name"=>"Last Name"
);

Inside input_array first index can be replaced with girl array as

 "girl"=>array("girl_id"=>2)

I want to create xsd to validate information as below:

 <xs:element name="xml">
    <xs:complexType>
      <xs:all>
        <xs:element ref="boy" minOccurs="0"/>
        <xs:element ref="girl" minOccurs="0"/>
        <xs:element ref="first_name"/>
        <xs:element ref="last_name"/>
      </xs:all>
    </xs:complexType>
  </xs:element>

Problem - I want to make sure either boy or girl information is there, first_name and last_name will always be there, how can I put them (girl,boy) either as choice or option. I would prefer to use xs:all so that element order should not be a problem.

I refereed this link to use so as to try using choice inside xs:all but could not get it working. I would appreciate any response. Thank you.

Was it helpful?

Solution

In the article you referenced (http://www.w3.org/wiki/Needs_choice_inside_all) they provide an example with substitution group. So, why not to use one?

Here's how it should look:

<xs:element name="xml">
  <xs:complexType>
    <xs:all>
      <xs:element ref="gender" minOccurs="1"/>
      <xs:element ref="first_name"/>
      <xs:element ref="last_name"/>
    </xs:all>
  </xs:complexType>
</xs:element>

<xs:element name="gender" abstract="true"/>
<xs:element name="boy" substitutionGroup="gender"> ... </xs:element>
<xs:element name="girl" substitutionGroup="gender"> ... </xs:element>

Specifically, I tried this full schema:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="xml">
    <xs:complexType>
      <xs:all>
        <xs:element ref="gender" minOccurs="1"/>
        <xs:element ref="first_name"/>
        <xs:element ref="last_name"/>
      </xs:all>
    </xs:complexType>
  </xs:element>

  <xs:element name="gender" abstract="true"/>
  <xs:element name="boy" substitutionGroup="gender"/>
  <xs:element name="girl" substitutionGroup="gender"/>

  <xs:element name="first_name" type="xs:string"/>
  <xs:element name="last_name" type="xs:string"/>
</xs:schema>

to validate this XML:

<?xml version="1.0" encoding="UTF-8"?>
<xml>
  <girl/>
  <first_name>Lara</first_name>
  <last_name>Croft</last_name>
</xml>

It worked! At that, if in place of <girl/> I specified <boy/>, it passed too, but did not when there was neither <girl/> not <boy/> or any of them together.

OTHER TIPS

Could you try this code?

<xsd:complexType name="column"> 
  <xsd:all>
    <xsd:element ref="gender" minOccurs="1"/>
    <xs:element name="firstname" type="xs:string"/>
    <xs:element name="lastname" type="xs:string"/>
  </xsd:all>
</xsd:complexType>


<xsd:element name="gender">
  <xsd:complexType>
   <xsd:choice>
     <xs:element name="boy" type="xs:integer" default="1"/>
     <xs:element name="girl" type="xs:integer" default="0"/>
   </xsd:choice>
  </xsd:complexType>
 </xsd:element>

The simplest approach is probably to rename boy_id and girl_id to gender (with an appropriate attribute value), as suggested by @herry. If you don't want to do this (why not?) then your remaining options include:

  • declare an abstract element gender_id, put it into the all-group, and declare boy_id and girl_id as being in its substitution group;
  • rename the enclosing element from 'xml' to 'girl' or 'boy' to carry the information about whether you are dealing with a girl or a boy

There are doubtless others, some of which will feel idiomatic to Java programmers and some of which will feel idiomatic to XML users.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top