Yossi Dahan [BizTalk]

Google
 

Thursday, September 22, 2005

Creating a schema that allows child elements to apear in any order

For a long time I was under the impression that in an xml document the order in which child elements appear under their parent element is not important.

I guess it comes down the fact that xml always seems to simply "make sense" and be flexible and readable that you wouldn't expect (well - I didn't!) that such thing as the order of elements would be inforced.
After all the impression is that while there's clearly a parent-child relationship in xml, there's no sibling relationship. not directly anyway.

The bottom line is that it does. when you simply create a sequence element the order in which the child elements appear in the schema is the order they must appear in the xml instance.

So...with the following xsd:
<xs:element name="Person">
<xs:complexType>
<xs:sequence>
<xs:element name="FirstName" type="xs:string" />
<xs:element name="LastName" type="x:string" />
</xs:sequence>
</xs:complexType>
</xs:element>

The following xml instance is valid:

<Person>
<FirstName>Yossi</FirstName>
<LastName>Dahan></LastName>
</Person>

but this one is not:

<Person>
<LastName>Dahan></LastName>
<FirstName>Yossi</FirstName>
</Person>

Now clearly both xml instances describe the same entity, and in this case, the order in which the child elements appear is irrelevant.

So - how do you create a schema in which the order is not enforced? quite simply it appears - by using a choice element.

<xs:element name="Person" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:choice maxOccurs="unbounded">
<xs:element name="FirstName" minOccurs="0"/>
<xs:element name="LastName" minOccurs="0"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>

Tthe important thing to notice is the maxoccurs on the choice element - this allows the actual repetition of each child element in the sequnce, but becuase they are in a sequence and both child elements have minoccurs=0 they can appear in any order.

It's been a while since I found the answer to this one, and at the time I thought I must be the only one being confused about this one, but recently I've seen/asked this question more then once so I've decided to mention this here.

Sunday, September 04, 2005

BizTalk, Web Services and Arrays

As part of the project I'm working on at the moment, I need to integrate some locally hosted logic with a NetSuite hosted e-commerce solution.

Until now (or at least recently) integration with NetSuite involved posting somewhat large Xml documents matching a (sort-of) standard called smbXml and parsing the response.
Classing work for BizTalk Server I have to admit.

But smbXml is one of those standards that only 2.5 applications worldwide use (WhatIs definition for smbXml) and also the web site www.smbxml.org has long vanished, so I was glad to find out NetSuite finally released a Web-Services-based API to replace it, after all - this is a much more standard approach - and even easier to work with in BizTalk Server.

That is until I found out they were possibly too standard as far as BizTalk Sever is concerned and decided, silly them, to use a feature of Web Services called "Support of Arrays"...

Trying to add a web reference to the NetSuite WSDL from my BizTalk 2004 project resulted in a nicely phrased error message basically saying - "this WSDL describes methods that return arrays - forget about it!".

BTW - trying the same from BizTalk 2006 resulted in a much less tidy error message.

I know this is a well known fact that BizTalk does not support web services that work with arrays, but it does not make it less annoying. Why should we be required to build helper classes to wrap calls to other relativley large products/services simply because they've been silly enough to support the standrad to it's full?

I also know that the WSE adapter supports arrays (see the tips towards the end of this article, but this does not help me add a reference to the web service and work with it in that seemeles way I'd expect from Visual Studio and BizTalk in all other scenarios.

Now I'm off to write that helper classs...