views:

342

answers:

4

I have a bit of a newbie xml schema question. I believe the answer is that what I need to do is not possible with schema, but I'd like to be sure. The problem is that I have a webservice that returns a response with one type of root element on success (say <Response>), and on a complete failure, returns a document with a different root element (say, <Exception>). So, basically, two completely different documents:

<Response>......</Response> OR
<Exception>....</Exception>

Is it possible to describe these two different documents with one schema document? It's like I want a choice as the first element under the schema element -- but that isn't valid syntax. I've tried a couple of variants that parse as valid xsd, but don't validate the documents. Any suggestions? Or is this simply not possible? Thanks very much in advance -- m

A: 

I think you can only have one root element. But I would think that you could make the root element <ResponseOrException> and then have it contain either a <Response> or an <Exception>.

As in this example.

John at CashCommons
Right -- that bit I understand (and may ultimately change the code to go that way, since I think it's a better approach anyway) -- but for now, I'm wondering if a choice of root elements is even a possibility.
mikey
No -- there is exactly one root element: http://www.w3.org/TR/2008/REC-xml-20081126/
John at CashCommons
The appropriate section in the standard is 2.1.
John at CashCommons
Hmmm -- this isn't quite relevant. I read that section as specifying only a single document root for well-formed xml. My xml would always have a single root either way. But that element varies, depending on whether an exception occurred on the call.
mikey
OK, how about this? "Type definitions form a hierarchy with a single root." Section 2.2.1 of this document which describes the schema definition: http://www.w3.org/TR/xmlschema-1/
John at CashCommons
That isn't referring to the document root. The link describes a definition as a form of schema component, and "Schema component is the generic term for the building blocks that comprise the abstract data model of the schema" So, each type definition forms a hierarchy, but those definitions can be combined to build schema.
chrisbunney
OK, thanks for the clarification. Glad I learned something today!
John at CashCommons
+6  A: 

Actually, XML schema does allow you to define alternative root elements in a single schema, although not by using the choice element. Instead, all you need to do is list each of the possible roots as direct children of your schema element.

For example, given the following XML schema:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"&gt;
    <xs:element name="foo">
        ...
    </xs:element>
    <xs:element name="bar">
        ...
    </xs:element>
</xs:schema>

Either of the following documents would validate against it:

<foo>
    ...
</foo>

Or:

<bar>
    ...
</bar>
Phil Booth
Validated this at http://tools.decisionsoft.com/schemaValidate/ so +1
chrisbunney
Geez -- that should have been obvious. Thanks!
mikey
+1  A: 

It's not possible, but the alternative isn't so bad. Just declare a root node that is typed as a choice, and have your application return a "response" node with a "success" or "exception" child. If you can't change the application, then you're out of luck, but with such a simple response, couldn't you create two different schemas, read the firstChild node, then apply the relevant schema?

<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema&quot;&amp;gt; <xs:element name="Response"> <xs:complexType> <xs:choice> <xs:element name="Success"/> <xs:element name="Exception"/> </xs:choice> </xs:complexType> </xs:element> </xs:schema>

Stephen Rushing
A: 

I came across this post and I thought it is worth mentioning what I figure from Spring Web Services world (those that give importance to data contract first).

One of the good ways of negotiating this root element problem is to directly define multiple root elements under the schema element like Phil Booth has mentioned.

However when it comes to best practices and web services framework that give priority to data first a fool proof schema design is important. When someone defines a schema like this -

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"&gt;   
<xs:element name="foo">   
    ...   
</xs:element>   
<xs:element name="bar">   
    ...   
</xs:element>   

a web service framework like Spring-WS, which relies on this so called data contract schema to generate the web service, may not be able to understand if <foo> or <bar> is the request root element to the service.

Please refer to this Link - Data Contract

In such cases, I have found the approach given by "John at CashCommons" or Stephen Rushing useful.

Hari Venkat