Can't suppress nodes in BizTalk mapping - biztalk

Afternoon all,
I'm learning BizTalk and am stuck on this problem.
There's a choice group with either telephone or address.
I can get the some of the address fields to be suppressed when outputting the telephone.
To make things simpler I'll just discuss the "CityName" field .
I've tried the following:
Mapped the "City" (text) node in the input file to "CityName" in the output. Connected an Exists logical functoid to the "Address1" node in the input node and the "CityName" in the output. I always get a city name with text filled in.
Mapped the "City" node in the input file and the Exists logical functoid to a Value Mapper functoid. Connected the Value Mapper functoid to the CityName in the output. I get a city name in the address node (Correct) and an empty node in the telephone node (Incorrect).
Mapped the "City" node in the input file and the Exists logical functoid to a Value Mapper (Flattening) functoid. Connected the Value Mapper (Flattening) functoid to the CityName in the output. I get a city name in the address node (Correct) and an empty node in the telephone node (Incorrect).
I thought one of the last two should have worked but both give an empty node instead of a suppressed node. The empty nodes have no attributes.
The CityName node is described by this schema type:
<xsd:complexType name="NameType">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="languageID" type="xsd:language" use="optional">
</xsd:attribute>
<xsd:attribute name="sequence" type="IntegerNumericType">
</xsd:attribute>
<xsd:attribute name="sequenceName" type="StringType" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:simpleType name="IntegerNumericType">
<xsd:restriction base="xsd:integer" />
</xsd:simpleType>
<xsd:simpleType name="StringType">
<xsd:restriction base="xsd:string" />
</xsd:simpleType>
Is there something in the type definition that's forcing an empty node to be created?
Thanks
EDIT: Below is the incorrect output. The second and third Communication nodes have
an Address Child node and should not.
I have a looping functoid on the phone numbers and the first address line in a flat input schema. That produces the three Communications nodes. I'm using a Logical Existance functoid on the address line to suppress the phone info in the first node. I have a Logical Not functoid on the output of that which is tied directly to the Address node in the output schema. I thought that should turn off the entire address node but it doesn't.
I tried adding a Value Mapping functoid connected to the Logical Existance functoid to the City Name and Postal code elements and that makes them empty, but they just will not go away. ARG!
I checked and the fields are all set to zero MinOccurs and I don't believe they're assigned a default value.
<ns0:Communication>
<ns0:Address>
<ns0:AddressLine sequence="1">1234 My St</ns0:AddressLine>
<ns0:AddressLine sequence="2">Apt. 2</ns0:AddressLine>
<ns0:CityName>Kansas City</ns0:CityName>
<ns0:CountrySubDivisionCode name="State">MO</ns0:CountrySubDivisionCode>
<ns0:CountrySubDivisionCode name="County">Jackson</ns0:CountrySubDivisionCode>
<ns0:CountryCode>US</ns0:CountryCode>
<ns0:PostalCode>64099</ns0:PostalCode>
</ns0:Address>
</ns0:Communication>
<ns0:Communication sequence="1">
<ns0:ChannelCode>Telephone</ns0:ChannelCode>
<ns0:UseCode>Personal</ns0:UseCode>
<ns0:DialNumber>1234567890</ns0:DialNumber>
<ns0:Address>
<ns0:CityName />
<ns0:CountryCode />
<ns0:PostalCode>64099</ns0:PostalCode>
</ns0:Address>
</ns0:Communication>
<ns0:Communication sequence="2">
<ns0:ChannelCode>Telephone</ns0:ChannelCode>
<ns0:UseCode>Business</ns0:UseCode>
<ns0:DialNumber>0987654321</ns0:DialNumber>
<ns0:Address>
<ns0:CityName />
<ns0:CountryCode />
<ns0:PostalCode>64099</ns0:PostalCode>
</ns0:Address>
</ns0:Communication>

It would help to have sample input and output xml snippets. Without that, I can guess at the xml structures. If they look something like this, then the below mapping should work fine:
Do your schemas look like that? The output produced by such a map is valid IF the <Choice> in the destination schema is set to Max Occurs = unbounded. If that's not the case, and if you can only have one Contact output, then you would have to only output the Phone if the Address is not there, like this:
Of course, that seems a bit silly, since one would expect to have both an Address and a Phone in the source xml, and the destination xml prevents you from having both.
If none of these scenarios matches up with yours, then please edit your question to provide more details.

The min & max occurrences on the schema defaults to 1. The mapper looks at that when generating the XSLT. Try setting Min Occur to 0.

The way to solve this issue is to use xsl directly instead of the built in mapper.
With xsl you can control when and how values are selected. That's very difficult
when using multiple looping functoids.

Related

Using A4SWIFT to generate SWIFT FIN MT103 results in empty multi-option SWIFT field tokens

We're using BizTalk and A4SWIFT to generate SWIFT FIN MT 103 messages.
When we're outputting to fields that have multiple options (eg. 57a, 57b, 57c, 57d) we should only have a single output (I'm calling this a field token). However, all available options are output, regardless of whether they should be.
Consider field 57, which can have options 57a, 57b, 57c and 57d.
In our testing, we're limiting to 57a and 57d for now.
We have a map from our source XML document/schema, which selects which fields to use and populates the A4SWIFT schema accordingly.
(I've blanked out irrelevant detail in the image)
In the example, we're looking for a string for the BIC ("ABCDEFGHXXX") and populating the A4SWIFT-side for field 57A IF that is true.
For the Name Address (57d), we check the NameAddress/Line1 field for an arbitrary string which we know will evaluate to false.
(The BIC is fictitious)
This works fine, except we also get an empty result for 57D, even though this should have evaluated to false.
:57A:/
ABCDEFGHXXX
:57D:/
We need 57D to not be there. If the condition Functoid returns False, the Value Mapping Functoid still seems to cause a result.
So we're thinking out Functoid selection isn't right. We've tried with Logical Existence, Logical String and String Equal.
How can we suppress unselected fields from appearing in our output SWIFT?
Try linking through a Equal or Not Equal Functoid directly to 57D and/or 57A. That will suppress the entire loop.

Accessing distinguished fileds in assign shape (Biztalk)

I am constructing a multipart message in construct shape. That message has a body part with distinguished field, which i want to assign in assignment shape:
As you can see, intellisense is suggesting me to select a node with my distinguished field. But when i select it, i get an error!
I've faced this before, and restarting VS always helped. But not this time :(
Message is a reserved word in XLang. Can you change the name of the element/attribute that backs this distinguished field to something else? If that does not work, you could always XPath to the element to read it and use it. Last if those two don't work, you could make this a promoted property where you are able to specify the name yourself.
Here is the list of reserved words.
http://msdn.microsoft.com/en-us/library/aa547020.aspx

BizTalk xml file to a flatfile format

Relatively new to BizTalk; I could use seasoned help.
I'm faced with having to try to map a source XML document to a flat-file TAB delimited destination. My source document has some nested nodes that I need to iterate through and translate them each as a row on the flat-file document; classic sales order header/detail relationship. The results would need me to repeat the header information for every nested element in the child node.
I've tried a solution using a looping functoid but I'm not sure how to represent the destination list correctly. Am I missing the obvious? At what destination row element should I link my "Looping" output param to?
For demonstration sake here's an example of the schemas I'm working with.
SOURCE SCHEMA (Don't have the possibility to modify the source structure)
schema\
salesorders\
salesorders\orders\
orders\soid
orders\cust name
orders\address
orders\detail\
orders\detail\msrp
orders\detail\modelno
orders\detail\sku
DESTINATION SCHEMA
schema\
\root\
soid
custname
address
etc...
Flat file OUTPUT (One line per detail item)
soid custname address msrp modelno sku
soid custname address msrp modelno sku
Anybody could orient me in right direction?
You'll link your Looping Functoid from the source node you want to have generate a new record to (usually) the outer-record node (usually first child of the Root, but not always) of the destination. This will basically tell the map "Every time you see a new blah in my source, create a whole new record in my destination."

Make a scripting functoid in a BizTalk map skip the output element

I'm using a scripting functoid in a BizTalk map. In a certain case, I want the destination element to be skipped (rather than empty).
I'm using inline C#. When I return null, the destination element is empty. Is there a way to make it skipped altogether?
Use a LogicalEquals functoid to determine if your input matches your case. Then map that output to a LogicalNot. Send the output of the LogicalEquals to one Mapping functoid (second input for Mapping will be the value of your field) and the output of your LogicalNot to another (same second input). Then map both of the value mapping functoids to your destination node.
Then, when your value equals your case, you'll send FALSE to the destination (instead of Null or Empty) and the node won't be output. Any other time, the LogicalNot will fire its Mapping Functoid and you should get your desired output.
Here's how I resolved it: (Please post an answer if you have a better way.)
Split the scripting functoid into two. The first one determines whether the destination element should exist at all and returns a boolean. The second one determines what value should be set in the destination (if any). Use these two scripting functoids as the inputs to a value mapping functoid.
Update: I didn't see Allen's similar answer when I posted this. I'll leave my alternative approach here in case it helps someone.

How to set a default value to an destination schema element in BizTalk Map

I have a requirement in BizTalk map, where
I will map some elements from source schema to destination schema,where the values will be assigned to destination schema elements based on some condition.
If those values are not assigned, i need to send some default value (N/A).
My map is not One-to-One so that i can use a scripting functoid and send a default value, on top of that the destination schema is a flat file and in source schema i have to loop a lot.
So can any body give me some suggestion about "How to set a Default value to a Element in Destination schema if nothing is mapped" using BizTalk Map/some setting in schema.
What I have already tried is, I Opened the destination schema for all the elements I have set the value 'N/A' to a property -> "DefaultValue" which was there in the property tab but when nothing is mapped the default value is not coming. Instead the node itself is not created in the Output file.
Please see the Map below for a good understanding
alt text http://www.biztalkgurus.com/cfs-filesystemfile.ashx/__key/CommunityServer.Discussions.Components.Files/13/0131.problem.JPG
Source Schema is a XML schema.
Destination Schema is a Flat file schema.
Now in the above map, in my source schema I am having a node called F4706 which will loop.
When the element "TypeAddressNumber" within the F4706 is "1", then I am mapping the remaining fields of that F4706 instance to "ship to" details in my destination schema
When the element "TypeAddressNumber" within the F4706 is "2",then I am mapping the remaining fields of that F4706 instance to "Reseller" details in my destination schema
When the element "TypeAddressNumber" within the F4706 is "3",then I am mapping the remaining fields of that F4706 instance to "EndUser" details in my destination schema
Now if I connect a Logical NOT functoid to the Logical Equal functoid and assign some default value, then the my destination node occurs Three times as one time the "=" functiod returns true one time and false other two times. But what I want is, if anything is there to map then map from "F4706" instance or assign the default value.
Find the INPUT File below
alt text http://www.biztalkgurus.com/cfs-filesystemfile.ashx/__key/CommunityServer.Discussions.Components.Files/13/5430.ip.JPG
The output I'm expecting and getting is :
alt text http://www.biztalkgurus.com/cfs-filesystemfile.ashx/__key/CommunityServer.Discussions.Components.Files/13/0724.curOP.JPG
Now if the Input file is like below :
alt text http://www.biztalkgurus.com/cfs-filesystemfile.ashx/__key/CommunityServer.Discussions.Components.Files/13/6403.otherIP.JPG
That is when I don't have a "F4706" node with TypeAddressNumber=2, I need to fill "N/A" in Reseller related nodes in my destination schema, which should look like below :
alt text http://www.biztalkgurus.com/cfs-filesystemfile.ashx/__key/CommunityServer.Discussions.Components.Files/13/0435.nextOP.JPG
If you go and check the XLST which is getting generated, it is writing a xsl:foreach so if you use xsl:choose/otherwise conditions gets checked multiple times and my output nodes gets duplicated.
I also tried to use some global variable in XLST in First Loop and and second loop to access that and write the default value, unfortunately it doesn't work too. Because a VARIABLE in XLST is not a TRUE variable. I think its a CONSTANT.
How to accomplish this ANY help is highly appreciated.
Put two "Value mapping" (Label them "Incoming" and "Default") on the map and drag the output from both to your destination (you will get a warning at compile time).
Put a "Logical NOT" on the map (Label it "NoValue").
Put a logical evaluation (Existence, IsNil, Length) that suits your need, to evaluate if you have an incoming value, and drag your source field to it. (Label it "HasValue")
Drag the result to the "Incoming" and the "Logical NOT".
Drag your source field to the "Incoming".
Drag the output from "NoValue" to "Default".
Add a constant parameter to "Default", by double clicking and insert new parameter, that is your default value.
Hope you understand this mess :)
I believe you are essentially trying to control the creation of an output node based on some condition.
I have tried this for records (you are trying to do this for elements, so I believe this should work for that as well).
I had connected the output of the Logical functoid to the record and the record was created only if the logical functoid returned true.
For default values, you are doing it the right way by putting the default value in the property grid for Schema element. So if nothing is mapped to this element, you will see in the xsl file that the element with the default value is generated.

Resources