BizTalk 2013r2 - Null elements in schemas - biztalk

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).

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
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.
MinOccurs = 1 is the default value if nothing is specified.
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.
<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).
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.

Related

xml2::xml_strip_ns() does not work on qualified xml?

I am trying to use R xml2 method xml_strip_ns on a xsd like this:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="Cell" type="Cell_type"/>
<xs:complexType name="Cell_type">
<xs:sequence>
<xs:element name="ID" type="id"/>
...
in order to be able to do xml_find_first(x,'./element') instead of xml_find_first(x,'./xs:element') but apparently strip does not care of working in this situation (it works with the example given in the function help though).
Am I missing something (I am absolutely new to xml so it wouldn't surprise me)?.
Thank you in advance for help,
Luigi

Validate XML Element for Mandatory value

I want to create an XSD for an XML. I have XML elements declared with the xs:string data type where that data is mandatory. I created an XSD and set minOccurs="1", but then found out that its purpose is to just check whether the element appears in the XML. I also discovered that there is a keyword use="required" but it is for attributes and cannot be used in the XML element. I finally tried nillable="false" but the XSD was validated without any data in my element.
This is my document:
<HelloWorld>
<Name></Name>
<Gender></Gender>
</HelloWorld>
And XSD:
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="HelloWorld">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="Name" minOccurs="1"/>
<xs:element type="xs:int" name="Gender"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Here I want the data in the Name element to always be present (it's a mandatory field). When I validate this file it will throw an error for Gender saying that it contains an invalid integer. If you put some numbers it will start validating successfully but it won't check the data inside the Name element.
It validates because an empty string is a valid xs:string. Gender fails when empty because an empty string is not a valid xs:int.
If you want to force Name validation to fail when empty, you have to add a restriction. You choose what kind of restriction you need: a minimum string length, certain string characters (an enumeration or a pattern), etc. In the example below, I added a restriction which requires that the string be at least one character long:
<xs:element name="Name" minOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
Now it will fail if Name is empty.

Text Box Not Accepting More Than 50 Characters?

I am using Report Viewer for my ASP.net application's reporting purpose.
The problem is, when I have data less than 50 characters in my table(DB is SQL Server) report works properly but when data goes beyond 50 characters it gives error as,
An error has occurred during report processing.
Cannot create a connection to data source 'DataSet1'.
Exception has been thrown by the target of an invocation.
Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints.
I cant't resolve the issue, PLease Help
thanks in advance
you can edit your dataset file with extension *.xsd with notepad
and then change maximum value for your column name/field name
example :
<xs:element name="InvDesc" msprop:Generator_ColumnVarNameInTable="columnInvDesc" msprop:Generator_ColumnPropNameInRow="InvDesc" msprop:Generator_ColumnPropNameInTable="InvDescColumn" msprop:Generator_UserColumnName="InvDesc">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="1000" />
</xs:restriction>
</xs:simpleType>
</xs:element>
i change maxlength from 50 to 1000
hope this will help you
Thank You
If you are using a TableAdapter:
Open Dataset and select the TableAdapter.
Select DataColumn giving this error and in the properties panel change the option MaxLength to the size you need

Jaxb sequence with unordered types

Using a schema and XML file I'm trying to create an element of Type A, that can contain nested elements of type A,B, and C. The element types A,B,and C are all extension of type X. So I wanted to create a inside of the type a element, and thought I could add any of elements A,B, or C in whatever order I wanted. Only A can have nested elements. I like this implementation because the ordering of the nested elements is important to our data model, and these elements will be a various order in the system.
<A>
<B></B>
<B></B>
<A>
<B></B>
<B></B>
<C></C>
<C></C>
</A>
<C></C>
</A>
I tried doing a few things in the XSD file to make this legal.
<xs:complexType name="A">
<xs:complexContent>
<xs:extension base="X" >
<xs:sequence>
<xs:element name="a" type="A" minOccurs="0" />
<xs:element name="b" type="B" minOccurs="0" />
<xs:element name="c" type="C" minOccurs="0" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
And I tried making the sequence contain only elements of the abstract type X, thinking I could use the concrete types A B and C in the XML file, but that got flagged as an error.
If I understand your use case correctly you can use the #XmlElementRef annotation to leverage the XML schema concept of substitution groups.
For More Information
http://blog.bdoughan.com/2010/11/jaxb-and-inheritance-using-substitution.html

BizTalk Looping Functoid

I have a structured XML file format that needs to be mapped to a flatter XML format. Ordinarily I would create a custom XSLT file for this and have the BizTalk map use it. However, I do like the idea of using the graphical maps where possible - it's all too easy to dive straight into XSLT but not so easy for those following you to quickly understand what the map's doing!
I suspect that the mapping could be acheived using the table looping function and table extractor functoid but I've tried for a couple of hours and failed :(
Note: I have no control over the source XSD - this comes from a third party. Here it is:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="VehicleTrips">
<xs:annotation>
<xs:documentation>Comment describing your root element</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence maxOccurs="unbounded">
<xs:element name="Vehicle">
<xs:complexType>
<xs:sequence>
<xs:element name="VehicleID"/>
<xs:element name="VehicleRegistration"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Trips">
<xs:complexType>
<xs:sequence maxOccurs="unbounded">
<xs:element name="VehicleId"/>
<xs:element name="Distance"/>
<xs:element name="Duration"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
...and here's the target XSD:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="Trips">
<xs:annotation>
<xs:documentation>Comment describing your root element</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence maxOccurs="unbounded">
<xs:element name="VehicleRegistration"/>
<xs:element name="Distance"/>
<xs:element name="Duration"/>
</xs:sequence>
</xs:complexType>
</xs:element>
To summarise, I need to look into Trips, grab the VehicleRegistration from Vehicle, keyed on VehicleId and copy the data across to the target schema.
Does anyone know whether / how this could be achieved using only functoids (or perhaps a little script in a scripting functoid)?
Many thanks,
Rob.
It looks like it could be done using looping and the logical equal functoid. if you can provide your actual schemas or just a subsample of data then it would be easier to figure out.
The source schema shown above make it look like you should be able to do it just with a looping functoid given you can have multiple .
is it possible to get a sub sample of the expected xml? how about an idea of how you expect your response file to look like. Do you expect to have multiple sequences of elements under the root? I think it would be easier if your target schema had a different root node.
ie.
<Trips>
<Trip>
<Registration />
<Distance />
<Duration />
</Trip>
</Trips>
Unless you use XSLT, i dont think you can maintain the order of the element sequence otherwise.

Resources