BizTalk 2013r2 - Null elements in schemas

330 views Asked by At

Trying to configure a schema so that it will always provide every element, regardless of whether it's populated or not.

I've tried setting the minOccurs to 1 and nillable to true on all elements in the schema, but it still doesn't make a difference. I've tested by passing through a message where the date element in the schema is null, but it still removes the element from the received message.

The payload is picked up via a WCF-SQL Typed Polling port, with the created message then sent direct into the message box for picking up downstream (the process creates a canonical payload accepted by multiple other downstream integrations).

Schema Example;

<xs:element minOccurs="1" name="account_id" nillable="true" type="xs:string" /> 
<xs:element minOccurs="1" name="hus_id" nillable="true" type="xs:string" /> 
<xs:element minOccurs="1" name="date_left" nillable="true" type="xs:date" />

WCF-SQL (Typed Polling) Source Data Example;

account_id - '267336302'
hus_id - ''
date_left - NULL

Received Message Example;

<account_id>267336302</account_id>
<hus_id/>

I've looked over the theory behind it, and in the first two pargraphs of this linked article, it's implied that these settings should make a difference.

BizTalk Mapper: Working With Nillable Values (xsi:nil=”true”) (Sandro's WordPress blog)

Can anyone suggest how I receiving the message with all elements as required (null value or not).

1

There are 1 answers

4
Dijkgraaf On

I was unable to re-produce the issue you are having.

I created a simple schema with on element which is a nillable date.

<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns="http://Scratch2.Schema.SO72560754" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" targetNamespace="http://Scratch2.Schema.SO72560754" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Root">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="NillableDate" nillable="true" type="xs:date" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

I made a second schema the same except I named the filed simply date.

<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns="http://Scratch2.Schema.SO72560754_out" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" targetNamespace="http://Scratch2.Schema.SO72560754_out" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Root">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Date" nillable="true" type="xs:date" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

And mapped the two together and deployed it to BizTalk.

I passed the following message through BizTalk with a XMLReceive Pipeline and the map on the Inbound Maps on the Receive Port.

<ns1:Root xmlns:ns1="http://Scratch2.Schema.SO72560754" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <NillableDate xsi:nil="true" />
</ns1:Root>

And got the expected output with the date field still there and being Nill.

<ns0:Root xmlns:ns0="http://Scratch2.Schema.SO72560754_out" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Date xsi:nil="true" />
</ns0:Root>

Note

  1. that there is a difference between empty field (either <Date/> or <Date></Date>) and a field that is Nill (<Date xsi:nil="true" />). If you are doing XML validation the empty dates would fail.
  2. MinOccurs = 1 is the default value if nothing is specified.
  3. If both source and destination elements are mandatory (e.g. must be there), then you don't need to do anything fancy, just map them as you would any other fields and no functoids necessary. It is only if the source is optional and the destination is mandatory that you have to do some fancy workarounds.

SQL

Yes, with the SQL Bindings, if the field is NULL then it will omit the field. A quick and dirty fix would be just to add some concatenate functoids in the map as below and have it concatenate to an empty string. This will produce a XML payload like below. Note: This would fail if you tried to validate it against the schema as an empty string is not a valid date, and also any numeric fields would also fail, but by default, BizTalk does not validate unless you tell it to.

enter image description here

<ns0:Root xmlns:ns0="http://Scratch2.Schema.SO72560754">
    <account_id>267336302 </account_id>
    <hus_id/>
    <date_left/>
</ns0:Root>

If you want to get XML that validates then you can follow Sandro's example, but all you have to do is rather than is the IsNill functoid, is to use the Logical Date Functoid and adjust the logic accordingly (as it inverts the true/false).

Map with logic for missing date

That will produce

<ns0:Root xmlns:ns0="http://Scratch2.Schema.SO72560754" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <account_id>267336302</account_id> 
  <hus_id /> 
  <date_left xsi:nil="true" /> 
</ns0:Root>

You could also use the Logical String and Logical Number functoids if you have fields of that type that you also want to have nillable="true" on.