views:

283

answers:

1

I've been trying to figure out how to use an XML Schema to validate XML files as I load them into an application. I've got that part working, but I can't seem to get the schema to recognise anything other than the root element as valid. For instance, I have the following XML file:

<fun xmlns="http://ttdi.us/I/am/having/fun"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://ttdi.us/I/am/having/fun
                          test.xsd">
    <activity>rowing</activity>
    <activity>eating</activity>
    <activity>coding</activity>
</fun>

with the following (admittedly generated from the visual editor—I am but a mere mortal) XSD:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema targetNamespace="http://ttdi.us/I/am/having/fun" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://ttdi.us/I/am/having/fun"&gt;
    <xsd:element name="fun" type="activityList"></xsd:element>

    <xsd:complexType name="activityList">
     <xsd:sequence>
      <xsd:element name="activity" type="xsd:string" maxOccurs="unbounded" minOccurs="0"></xsd:element>
     </xsd:sequence>
    </xsd:complexType>
</xsd:schema>

But now, using Eclipse's built-in (Xerces-based?) validator, I get the following error:

cvc-complex-type.2.4.a: Invalid content was found starting with element 'activity'. One of '{activity}' is expected.

So how do I fix my XSD so that it…works? All the search results I've seen so far seem to say "…so I just turned off validation" or "…so I just got rid of namespaces" and that's not something I want to do.

ADDENDUM:

Now let's say I change my schema to this:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema targetNamespace="http://ttdi.us/I/am/having/fun"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://ttdi.us/I/am/having/fun"&gt;
 <xsd:element name="activity" type="xsd:string"></xsd:element>

 <xsd:element name="fun">
  <xsd:complexType>
   <xsd:sequence>
    <xsd:element ref="activity" minOccurs="0" maxOccurs="unbounded"/>
   </xsd:sequence>
  </xsd:complexType>
 </xsd:element>
</xsd:schema>

Now it works, but does that method mean that I'm allowed to have <actvity> at the root of my document? And if the ref should just be substituted as-is, then why can't I replace ref="actvity" with name="activity" type="xsd:string"?

ADDITIONAL ADDENDUM: ALWAYS do this, or else you will spend hours and hours banging your head on a wall:

DocumentBuilderFactory dbf;
// initialize dbf
dbf.setNamespaceAware(true);
+1  A: 

This XSD validates properly here:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema targetNamespace="http://ttdi.us/I/am/having/fun" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://ttdi.us/I/am/having/fun"&gt;

  <!-- definition of simple element(s) -->
  <xsd:element name="activity" type="xsd:string"></xsd:element>

  <!-- definition of complex element(s) -->
  <xsd:element name="fun">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element ref="activity" maxOccurs="unbounded" minOccurs="0"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

</xsd:schema>
Adam Bernier
so, is putting all those elements in the root of the document the "right"/accepted thing to do? It just seems a bit funny first looking at it.
Paul Fisher
You could just as easily specify the 'activity' element inside of the 'fun' element (instead of using the 'ref' attribute): <xsd:element name="activity" type="xsd:string" maxOccurs="unbounded" minOccurs="0"/> However, if your schema becomes more complex you may prefer breaking up the definitions as above. Both methods are "right/accepted".
Adam Bernier
But then if I do what you suggest in this comment, it breaks again, with the same error message as before. I'm utterly puzzled. and I feel like I'm missing something fundamental.
Paul Fisher
Add elementFormDefault="qualified" to your schema element (<xsd:schema ...>) and you should be good to go.
Adam Bernier
Mr. Bernier: ONE (1) INTERNET TO YOU.
Paul Fisher
To answer your other question: an XML document with an 'activity' element at the root would NOT validate against my XSD. Also, your 2nd XSD has a small typo: ref="activity" should be name="activity"
Adam Bernier
It turns out that this and other related problems were (at least partially) due to the fact that I hadn't enabled namespace support in my parser, which made things Very Difficult Indeed.
Paul Fisher