Tag Archive: XSD Schema

I was recently confronted with an interesting problem where I was asked to design a BizTalk schema which contained a complex type that must contain at least one instance of some of its child elements or optionally some or all of them. Upon questioning the business requirement it turned out that I didn’t actually have to enforce this in the schema as this level of business logic was better served by a downstream system. However I did decide that this was an interesting enough scenario (albeit not necessarily a common or practical one) to dive into it a bit deeper and see how it could be implemented using an XSD schema. Note that while I have used BizTalk 2009 schema editors in Visual Studio 2008 to create my schemas, aside from the wording of error messages nothing in this blog post is really BizTalk specific.

Let’s assume that we are dealing with the XML structure below and we are advised that the record structure must always contain either an Element1 or an Element2 element or both (the rest of the elements are all optional).

Basic XML structure

One way we can achieve the above goal is by making use of choice structures as below.

2 Elements Untyped

Note that in the above screenshot the choice consisted of a sequence that contained both Element1 and an optional Element2, and a second sequence that contained only Element2. This caters for scenarios where both elements exist, or only one exist. See the below screenshots which illustrate that if either Element1 or Element2 are missing then that is not a problem but if both are missing then the XML message is invalid.

Valid NoElement2 Valid NoElement1 Invalid NoElement1or2

When I originally approached the problem I thought of creating a choice structure with three sequences, one with Element1, the second with Element2, and the third with Element1 and Element 2. However this is not allowed and trying to implement this will result in an error stating “Multiple definitions of element xxx causes the content model to become ambiguous…” as below.

Ambiguous error

Now what if we want to change the data type for Element2 (which exists in both of the sequences in the choice). If we try to change the data type from string to int on the Element2 element in one of the sequences using the BizTalk/Visual Studio schema editor we will get an error stating “Elements with the same name and in the same scope must have the same type” as below.

Same type error

The reason for this is that the data type must be the same for elements with the same name that exists in multiple sequences in a choice structure. Changing them one at a time is not an option. One way to get around this is to open the schema using an XML editor and to change the data type for both of the Element2 elements at the same time. An even cleaner solution would be to extract the definition of Element2 into a simple type, and to have both Element2 elements use the simple type as their type so that if the data type for Element2 needed to be changed it would only have to be changed on the simple type in the future. In the below screenshot this has been done for Element1, Element2, Element3, Element4, and Element5 and we are now enabled to change data types with ease.

2 Elements Typed

Now what if we wanted to add Element3 to the choice as well, the new rule stating that at least one of Element1, Element2, or Element3 are provided, or any combination of two or three of the elements are provided. This can be achieved quite easily with the below structure. Note that the pattern is to have all the elements in the first sequence where only Element1 is mandatory, then to remove Element1 in the second sequence with Element2 now being mandatory, and the third sequence only containing Element3 which is now mandatory. Adding more elements to the mix would require you to extend this pattern.

3 Elements

How about if Element2 is always mandatory, and you additionally also need to provide either Element1 or Element3 or both elements. You can achieve this with the below structure.

Element2 Mandatory

I hope that this blog post has illustrated to you how you can create schemas that specify multiple combinations of optional/mandatory rules for a given complex type through the use of choice structures with child sequence groups.

When creating schemas I typically follow the rule that each xsd file contains one root node only.

However when dealing with schemas that have been generated from metadata it is quite common for schemas to be generated with multipe root nodes.  In the case of web services all the request and response schema definitions across all the operations would be generated in one file, and similar behavior would be observed when generating schemas for the WCF-SQL adapter.  I would recommend sticking with this file structure, as it will minimize the pain you need to go through in case you need to regenerate the schemas and just want to overwrite the existing files.

How bad a typist does one have to be to misspell HelloWorld?

By default when you deploy a project that contains one of these multi root node schemas, all the schemas are available to the BizTalk runtime.

What you’ll quickly find though is that if you try to use options such as validate instance or generate instance, BizTalk will always do so with the first root node defined in the xsd file.   Luckily there is a way to override this by changing the “Root Reference” property against the schema.  You will see this property by clicking on the “Schema” node which is at the top of the schema hierarchy and then looking in the properties section of Visual Studio.

If you click on the dropdown, you will be faced with a list of all the root nodes in the schema file.  Choosing one of the root nodes will now instruct Visual Studio to treat that root node as the only valid one for that schema file.

The implication of this is that you can now run validate instance and generate instance against that schema file for the root node you have specified.  However another implication is that when you do a deployment from Visual Studio, you will find that only the root node that was set in root reference has been deployed, the rest of the root nodes are not available to the BizTalk runtime.

Where have all the schemas gone?

So moral of the story is that Root Reference is a powerful property that will allow you to validate or generate instances of the correct root node in your schema file, and can also be used to only deploy one of the root nodes defined in the schema file.  If you want to deploy all the root nodes in the schema file, do remember to set the Root Reference property back to (Default).

%d bloggers like this: