Sunday, October 30, 2011

BizTalk Mapper vs Attributes with Defaults….Schema Elements with an attribute having a default value are ALWAYS generated

 

‘Challenge’:

Schema Elements with an attribute having a default value are ALWAYS generated, this is because of the default mapping behavior.

Structure of this post:

What is the problem

Attributes with a Default Value are generated even though the element is optional. Consider this schema, which has an Data element.

image

The element ‘OptionalAttributeDefault’ is optional (minoccurs:0) and has an attribute with a Default value: ‘LINUX’

image

The element ‘RequiredAttributeDefault’ is mandatory (minoccurs:1) and has an attribute with a Default value: ‘CAT141.12’

image

The element ‘RequiredDefaultValue’ is mandatory (minoccurs:1) and has a default value: ‘Test’

image

When we execute the map which does not map the ‘Data’ element like this:

image

The XML output generated is:

<ns0:Destination xmlns:ns0="http://AttributeTest.Schema2">
    <Name>Name_0</Name>
    <ID>ID_0</ID>
    <Data>
        <OptionalAttributeDefault Type="LINUX"></OptionalAttributeDefault>
        <RequiredAttributeDefault Type="CAT141.12"></RequiredAttributeDefault>
        <RequiredDefaultValue>Test</RequiredDefaultValue>
    </Data>
</ns0:Destination>

Issue: All [DATA] elements are generated, optional elements with an attribute default as well

 

Why is this

This is because the .btm file is configured with a behavior to always generate the default values, even for optional elements.

Although we can state that the default values have to be removed, that is not always possible. I came across this issue when implementing UBL (from OASIS).

 

How to overcome this

We can overcome this be altering the behavior of the map, this can be done by opening the .BTM file and navigate to the attribute: ‘GenerateDefaultFixedNodes’, which is default “YES”.

Before making any changes, we have to understand which options there are:

  • GenerateDefaultFixedNodes=”Yes” : default behavior
  • GenerateDefaultFixedNodes=”” : this will generate no elements if the attribute has a value, even when the element is mandatory!

Note: you can set the value to whatever (no, false, etc) however when you save the map it will become “”

Example result:

<sns0:Destination xmlns:ns0="http://AttributeTest.Schema2">
  <Name>Name_0</Name>
  <ID>ID_0</ID>
</ns0:Destination>

Issue: No [DATA] element is generated

  • GenerateDefaultFixedNodes=”RequiredDefaults” : this will generate elements with minoccurs=1 in case it has attributes with a default value

Example result:

<ns0:Destination xmlns:ns0="http://AttributeTest.Schema2">
    <Name>Name_0</Name>
    <ID>ID_0</ID>
    <Data>
        <RequiredDefaultValue>Test</RequiredDefaultValue>
    </Data>
</ns0:Destination>

Issue: results are still not valid (Required elements with default attribute value are not created, thus validation fails

 

This means that even though you can configure the behavior of the mapping there is no perfect solution. You either have:

  • to modify the default values and use the default behavior
  • have to ensure that elements/attributes are set (you can not rely on any of the default attributes anymore since elements are not created)

 

Since this is quite important, I’ve created a sample project that has a map for each setting, and a readme.txt with information about the results.

In the next post I will explain how to change the ‘template’ used when creating maps.

HTH,

Sander Nefs

 

No comments: