Some programs depend on a distinction between a null array and an empty array. What is often used to represent arrays in XML schemas does not have any such distinction. Is there anything you can do to get around this feature of XML? This article will show you.
When working with Web services, it is all too often assumed that anything that can be done in a programming language can be done in XML. There are many cases where that is not true. This tip addresses one of those cases: the distinction between an array which is null, and an array which has no elements.
An XML array
Most programming languages, like the Java language, have the concept of an array: a sequential collection of like elements. XML also has a sequential collection of like elements: an XML schema element with a maxOccurs attribute whose value is greater than 1. So it stands to reason that the Java language's sequential collection of like elements would map nicely to XML's sequential collection of like elements. Listing 1 defines a complexType which contains such an XML schema 'array'.
Listing 1. A complexType containing an 'array'
The problem
This XML "array" is not strictly an array. It is an element with an occurrence constraint, which means that the element is defined to occur a specific number of times, in this case 0 or more times. This does sound a lot like an array, and for most intents and purposes, it is. But the mapping isn't perfect. You should be aware of the shortcomings so they don't catch you by surprise.
Following the JAX-RPC mapping rules, the complexType in Listing 1 would become the Java bean in Listing 2 (actually, the bean would have getters and setters, but we'll keep it simple for this discussion).
Listing 2. A bean containing an array.
public class Bean {
public java.lang.String name;
public java.lang.Integer[] array;
}
(Note that Bean's array variable is an array of java.lang.Integer, not an array of int. The array element from the XML schema is nillable. A Java int cannot be null. A java.lang.Integer can be null. So we use java.lang.Integer in this mapping.)
number of examples of mapping an instance of the Java Bean to an instance of the corresponding XML. The first row is the Java representation; the second row is the corresponding XML representation.
One obvious thing to note about Table 1 -- and it's the topic of this tip -- is that an empty instance of a Java array and a null instance of a Java array map to the same XML instance. This is not good if you're depending on a distinction between the two.
One easy trap to fall into here is to guess that a null array inside a bean is really represented by the XML in the second column. But as we hope we've shown in the table, that really represents an array with a single element whose value is null, not a null array.
Is there a way around this issue?
Of course! The thing to be aware of is that an array in most programming languages is really made up of two things: there are the contents of the array and there is the array itself -- a wrapper, if you like, around the contents. An XML "array" is only a list of the elements. There is no wrapper.
So the solution is simple: create a wrapper for the array, as shown in Listing 3.
Listing 3. A bean containing a wrappered array.
As you can see, the empty instance and the null instance of the arrayWrapper complexType are distinct from each other.
This solution isn't a cure-all. First of all, it's rather more complex than a simple minOccurs/maxOccurs representation of an array. Secondly, instead of a simple bean containing an array, this XML schema really looks like a bean containing a bean containing an array; and that's likely what you'll end up with if you map this XML schema into Java programming with your favorite JAX-RPC WSDL-to-Java tool. Until standards bodies recognize and map this wrapped array pattern appropriately, this solution is something you should apply only if you really must distinguish a null array from an empty array.
Summary
XML "arrays" are not truly arrays in a programming language sense. XML does not distinguish between a null array and an empty array. There is an XML schema pattern that you can follow to get the equivalent distinction, but this pattern is not well recognized by standards bodies and should only be used when absolutely necessary.
Web services programming tips and tricks: