views:

161

answers:

2

Hi,

Ia processing an email and saving some header inside a xml document. I also need to validate the document against a xml schema.

As the subject suggest, I need to validate ignoring the elements order but, as far as I read this seems to be impossible. Am I correct?

If I put the headers in a<xsd:sequence>, the order obviously matter. If I us <xsd:all> the order is ignored but for some strange reason this imply that the elements must occur at least once.

My xml is something like this:

<headers>
  <subject>bla bla bla</subject>
  <recipient>[email protected]</recipient>
  <recipient>rcp02domain.com</recipient>
  <recipient>[email protected]</recipient>
</headers>

but I think the final document is valid even if subject and recipient elements are swapped.

There is really nothing to do?

+2  A: 

Yes, it is possible. Just create a choice (in some type or element content model, of course) with maxOccurs set to unbounded.

<xs:element name="headers">
    <xs:complexType>
        <xs:choice maxOccurs="unbounded">
            <xs:element name="subject" type="xs:string"/>
            <xs:element name="recipient" type="xs:string"/>
        </xs:choice>
    </xs:complexType>
</xs:element>
xcut
@segolas, I can see that this solution meets your requirement, please show courtesy to accept the solution.
infant programmer
I'm working on Netbeans, and using this solution gives me some errors I'm trying to figure out. So, by now I don't know if this answer works or not!
Segolas
Hum... i think it worked, but right now jaxb generate a method getSubjectOrRecipient() instead of getSubject() AND getRecipient().According to http://www.w3schools.com/Schema/el_choice.asp "XML Schema choice element allows only one of the elements contained in the <choice> declaration to be present within the containing element." So, it seems I can only have subject OR recipient inside the headers element... am I right?
Segolas
Hi segolas; FYI, if you are using JAXB, then as soon as you create an unbounded sequence or unbounded choice (rather than unbounded elements within them), then JAXB is forced to generate this intermediate method to correctly reflect the repeating choice. However, regardless: you can repeat the elements as often as you want. Each choice can only have one, yes, but the choice itself is repeatable :)
xcut
Ok, got it. Just one thing, I want both <subject> and <recipient> and a xml without one of these two tags should be invalid.Is this the case? Maybe I can try with minOccurs=1 ?
Segolas
The default for minOccurs is 1 in any case. Unfortunately, the thing you want (unlimited mixed list AND at least one of each item) is impossible to express in XML Schema.. you'll have to validate it on the JAXB graph after loading.
xcut
Ok, perfect. Thanks for your time!
Segolas
A: 

First, some requirement guessing:

  • "subject" is mandatory
  • At least one "recipient" is mandatory

Since you have only two different elements it is very easy to accomplish it:

<xs:element name="headers">
<xs:complexType>
 <xs:choice>
   <xs:sequence><!-- The recipient MUST be after the subject -->         
     <xs:element name="subject" type="xs:string" />
     <xs:element name="recipient" minOccurs="1" maxOccurs="unbound" type="xs:string" />
   </xs:sequence>
   <xs:sequence><!-- The recipient is before the subject -->          
     <xs:element name="recipient" minOccurs="1" maxOccurs="unbound" type="xs:string" />
     <xs:element name="subject" type="xs:string" />
     <xs:element name="recipient" minOccurs="0" maxOccurs="unbound" type="xs:string" />
   </xs:sequence>
 </xs:choice>
</xs:complexType>
</xs:element>
Unfortunaly I posted just an example of what my xml is and in fact I have lots of elements. I understand your solution but I think would make my schema less readable and a little too hard to maintain...
Segolas