XML XSD Schema: Use element ref, multiple child element

Hi,
I need to create an xsd file for client who will then create xml file, validate against xsd.
<?xml version="1.0" encoding="iso-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <Root>
    <A>
      <E>
        <B>
          <C/>
        </B>
      </E>
    </A>
    <A>
      <D>
        <B>
          <C/>
        </B>
      </D>
    </A>
  </Root>
</xs:schema>

<!--<A> can have either <E> or <D> as child.-->
<!--<C> is always child of <B>-->
<!-- 1. How can I define this in XSD? -->
<!-- 2. How do I define <B> and <C> only once and use later as reference? -->
VakilsDeveloperAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

mccarlIT Business Systems Analyst / Software DeveloperCommented:
Can you provide further information as to if any of those elements are optional or if any of them can  have multiple child elements?
0
VakilsDeveloperAuthor Commented:
Hi,
None of the elements are optional, regarding child elements:
Element B can appear multiply. But for each B, there must be at least one C.  So it could be like
A
 E (or D) (once for each A)
    B (must follow E or D one or more times, but each instance must be followed by C)
       C
    B
       C   ( must follow B, one or more times)
       C
 A
   D
     B
       C
       C
  A
      E
         B
            C
     Thanks. That was good question. Let me know if you need additional clarity.
0
mccarlIT Business Systems Analyst / Software DeveloperCommented:
Ok the following should do what you want. Note that it is still unclear from the above whether the D and E elements are different in the element name ONLY or if in the real world they might have other differences, such as different attributes, etc. The below XSD allows D and E to have some differences but if they aren't different at all (except for the element name) then you could remove one of the DType or EType types and then define boths elements as the one type. (If that is unclear and possibly what you want, let me know and I'll change the schema)

Also, note that it is not strictly necessary to define a type for each element, it is generally the way I do it because I think it makes it clearer as to what is going on.

<?xml version="1.0" encoding="iso-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
	
	<xs:element name="Root" type="RootType"/>
	
	<xs:complexType name="RootType">
		<xs:sequence>
			<xs:element maxOccurs="unbounded" name="A" type="AType"/>
		</xs:sequence>
	</xs:complexType>
	
	<xs:complexType name="AType">
		<xs:choice>
			<xs:element name="E" type="EType"/>
			<xs:element name="D" type="DType"/>
		</xs:choice>
	</xs:complexType>
	
	<xs:complexType name="EType">
		<xs:sequence>
			<xs:element maxOccurs="unbounded" name="B" type="BType"/>
		</xs:sequence>
	</xs:complexType>
	
	<xs:complexType name="DType">
		<xs:sequence>
			<xs:element maxOccurs="unbounded" name="B" type="BType"/>
		</xs:sequence>
	</xs:complexType>
	
	<xs:complexType name="BType">
		<xs:sequence>
			<xs:element maxOccurs="unbounded" name="C" type="CType"/>
		</xs:sequence>
	</xs:complexType>
	
	<xs:complexType name="CType">
		<!-- Add you definition, if any, of C in here -->
	</xs:complexType>
	
</xs:schema>

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Cloud Class® Course: Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

VakilsDeveloperAuthor Commented:
Hi mccarl,
I have created xml with realistic values below:
Root is Movies
A is Movie
E is DVD_Release
D is Theatrical Release
B is Actor, child of E &D.
C is Payment, child of B
Rules are the same. Movie is either followed by Theatrical or DVD Release, which is followed by Actor, which is again followed by Payment. Theatrical or DVD can have multiple Actor, but each Actor must be followed by at least one Payment, there could be multiple Payment.
So, tree is:
                Movies
                              Movie ( can have either DVD or Theatrical)                          
                                     DVD (one per movie)
                                         Actor (many per DVD, each Actor is followed by Payment)
                                                 Payment (Many per Actor)
                                   Theatrical(one per movie)
                                        Actor( same rules)
                                                 Payment (Same)
  Let me know if you have questions.                                      


<?xml version="1.0" encoding="utf-8"?>
<Movies>
  <Studio>Paramount</Studio>
  <Productions>JHWarner</Productions>
  <Movie>
    <Movie_Name>Far From Madding Crowd</Movie_Name>
    <Length>180</Length>
    <DVD_Release>
      <Media_Type>DVD</Media_Type>
      <Media_Code>2H5-BluRay</Media_Code>
      <Actor>
        <Name>John Madison</Name>
        <Role>Lead</Role>
        <Payment>
          <Invoice_Number>A123</Invoice_Number>
          <Amount>256.33</Amount>
        </Payment>
        <Payment>
          <Invoice_Number>A124</Invoice_Number>
          <Amount>100</Amount>
        </Payment>
      </Actor>
      <Actor>
        <Name>Virgina Watson</Name>
        <Role>Lead</Role>
        <Payment>
          <Invoice_Number>A125</Invoice_Number>
          <Amount>300</Amount>
        </Payment>
      </Actor>
    </DVD_Release>
    <Theater_Release>
      <Release_Date>2015-01-23</Release_Date>
      <First_Week_Gross>350</First_Week_Gross>
      <Actor>
        <Name>Virgina Watson</Name>
        <Role>Lead</Role>
        <Payment>
          <Invoice_Number>A128</Invoice_Number>
          <Amount>400</Amount>
        </Payment>
      </Actor>
    </Theater_Release>
  </Movie>
 
</Movies>
0
mccarlIT Business Systems Analyst / Software DeveloperCommented:
Let me know if you have questions.

No, I don't have any questions. Do you? I didn't see any questions in the comment above. :)
0
VakilsDeveloperAuthor Commented:
I wanted an xsd based on above xml, as the original xml submitted was kind of abstract, and to give you a clear picture on xml that makes sense. But I now get some idea based on your xsd and will try to fill in the values and go by you.
Thanks, sorry for confusion.
0
mccarlIT Business Systems Analyst / Software DeveloperCommented:
;) Don't worry about me, I was just being difficult because I knew that there wasn't too much to go from the abstract version I gave you to the realistic one. I think you could literally do a case sensitive find/replace of "find Root replace with Movies" and similarly "find A replace with Movie", etc. and you'd be 90% there.

Then you just need to add in the extra detail elements within their parents. But these are easy because all the extra elements (as far as I can tell) are all what are called "simple" elements in that they don't have further children just text values, so for example, you just add this line to the definition of RootType (now should be MoviesType)...

    <xs:element name="Studio" type="xs:string"/>

Open in new window


... and so on for all the new elements, adding them to the appropriate parent elements. Note that because they are "simple" types there is no extra "xs:complexType" definition for these ones.

One extra thing that I will say is that in XSD, sequences constrain the order of the elements too. So if in the Movies root element the data is always in order of Studio, Productions, Movie, Movie, Movie, ... then that is the order that they need to appear in their complexType definition.
0
VakilsDeveloperAuthor Commented:
OK. Got it. Will do tomorrow and post. It's almost 11pm PDT, and end of summer :(
0
mccarlIT Business Systems Analyst / Software DeveloperCommented:
No worries, good luck and yeah, I will have a look over it when you can post it. 4 in the afternoon here in Australia and the weather is just warming up nicely! ;)  Good night
0
VakilsDeveloperAuthor Commented:
Well, finally: the xsd. I struggled as it would give me an option of DVD_Release only after the element if it appeared first. At Movie level it gave me both choices DVD and Theatrical. But once DVD_Release appeared in xml it did not give me both options after the element, only DVD_Release.
I came across this article: How to extend a choice complexType without sequencing the choice?
http://stackoverflow.com/questions/9008622/how-to-extend-a-choice-complextype-without-sequencing-the-choice
So I put max, min at choice level rather than element level. And that worked.
Let me know if that's OK or any gotcha's in this.
The XSD:
<?xml version="1.0" encoding="iso-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:element name="Movies" type="MoviesType"/>

  <xs:complexType name="MoviesType">
    <xs:sequence>
      <xs:element  name="Studio" type="xs:string"/>
      <xs:element name="Productions" type="xs:string"/>
      <xs:element maxOccurs="unbounded" name="Movie" type="MovieType"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="MovieType">
    <xs:sequence>
      <xs:element name="Movie_Name" type="xs:string"/>
      <xs:element name="Length" type="xs:string"/>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element name="DVD_Release" type="DVD_ReleaseType"/>
        <xs:element name="Theater_Release" type="Theater_ReleaseType"/>
      </xs:choice>
    </xs:sequence>
  </xs:complexType>
 
  <xs:complexType name="Theater_ReleaseType">
    <xs:sequence>
      <xs:element name="Release_Date" type="xs:date"/>
      <xs:element name="First_Week_Gross" type="xs:decimal"/>
      <xs:element maxOccurs="unbounded" name="Actor" type="ActorType"/>
    </xs:sequence>
  </xs:complexType>
 
  <xs:complexType name="DVD_ReleaseType">
    <xs:sequence>
      <xs:element name="Media_Type" type="xs:string"/>
      <xs:element name="Media_Code" type="xs:string"/>
      <xs:element maxOccurs="unbounded" name="Actor" type="ActorType"/>
    </xs:sequence>
  </xs:complexType>



  <xs:complexType name="ActorType">
    <xs:sequence>
      <xs:element name="Name" type="xs:string"/>
      <xs:element name="Role" type="xs:string"/>
      <xs:element maxOccurs="unbounded" name="Payment" type="PaymentType"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="PaymentType">
    <xs:sequence>
      <xs:element name="Invoice_Number" type="xs:string"/>
      <xs:element name="Amount" type="xs:string"/>
      <!-- Add you definition, if any, of C in here -->
    </xs:sequence>
  </xs:complexType>

</xs:schema>
0
mccarlIT Business Systems Analyst / Software DeveloperCommented:
Let me know if that's OK or any gotcha's in this.

Well first you will need to clarify the requirement again for me, as it seems to have changed. At first I read...

<!--<A> can have either <E> or <D> as child.-->
E (or D) (once for each A)
Movie is either followed by Theatrical or DVD Release


... which I took to mean that Movie (A) can have 1 DVD (D) OR 1 Theatrical (E) element.

I didn't notice in your last example that now you are saying that it can be DVD or Theatrical OR BOTH.

So let's fully clarify what you are after... This is what I now assume you want.

<Movie> must have at least one <DVD> or <Theatrical> element
<Movie> can have both <DVD> and <Theatrical> elements

Can <Movie> have multiple of either <DVD> or <Theatrical>? Say you have a normal DVD release and then a "Directors Cut" release? Or a DVD and a BluRay release?
1
VakilsDeveloperAuthor Commented:
You are really sharp. A Movie cannot have both. It can be either DVD(multiple) or Theatrical(multiple) (in our world).  So my xml is wrong. Before Theatrical Release, there needs to be Movie element in the xml.

Movie
   DVD
      Actor
         Payment
    DVD
        ...
  Movie
      Theatrical
          Actor
             Payment.
       Theatrical
            ...
0
mccarlIT Business Systems Analyst / Software DeveloperCommented:
Ok, but there can be multiple DVD OR Theatrical, so it sounds like what you had when you said before that you "struggled" with it is actually what you want. Did you have the definition for MovieType like this...

  <xs:complexType name="MovieType">
    <xs:sequence>
      <xs:element name="Movie_Name" type="xs:string"/>
      <xs:element name="Length" type="xs:string"/>
      <xs:choice>
        <xs:element maxOccurs="unbounded" name="DVD_Release" type="DVD_ReleaseType"/>
        <xs:element maxOccurs="unbounded" name="Theater_Release" type="Theater_ReleaseType"/>
      </xs:choice>
    </xs:sequence>
  </xs:complexType>

Open in new window

0
VakilsDeveloperAuthor Commented:
Yes, that is exactly what I wanted. Now all looks good. The element Movie is actually Movie_Contract, that is I may have the contract for DVD release and not theatrical release.
So the final files:
XMLFile4.xmlXMLSchema4.xsd
0
VakilsDeveloperAuthor Commented:
Thanks for the solution and walk-thru. I appreciate that you caught up quick on my requirements and steered me close to solution. It was fun!
Regards,
-vakils-
0
mccarlIT Business Systems Analyst / Software DeveloperCommented:
You're welcome! :)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
XML

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.