BizTalk Flat File Schema - file header and footer but no records - biztalk

I'm dealing with a flat file that has a tagged and pipe delimited header, positional body records, and a positional footer
H|20220601|XXXX
CONTENT FIELD 1 CONTENT FIELD 2 CONTENT FIELD 3
CONTENT FIELD 1 CONTENT FIELD 2 CONTENT FIELD 3
F00001234
I'm having an issue getting rid of this error:
Reason: Unexpected end of stream while looking for:
Positional data (length is X)
The current definition being parsed is Records. The stream offset where the error occured is XX. The line number where the error occured is 3. The column where the error occured is 0.
when I get an empty file like:
H|20220601|XXXX
F00001234
This is my flat file schema
<xs:element name="Root">
<xs:annotation>
<xs:appinfo>
<b:recordInfo suppress_trailing_delimiters="false" preserve_delimiter_for_empty_data="true" sequence_number="1" child_order="postfix" child_delimiter="0xD 0xA" child_delimiter_type="hex" structure="delimited"/>
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:annotation>
<xs:appinfo>
<groupInfo xmlns="http://schemas.microsoft.com/BizTalk/2003" sequence_number="0"/>
</xs:appinfo>
</xs:annotation>
<xs:element name="Header" maxOccurs="1" minOccurs="1">
<xs:annotation>
<xs:appinfo>
<b:recordInfo suppress_trailing_delimiters="false" preserve_delimiter_for_empty_data="true" sequence_number="1" child_order="infix" child_delimiter="/" child_delimiter_type="char" structure="delimited" tag_name="H"/>
</xs:appinfo>
</xs:annotation>
<xs:complexType>
[...]
</xs:complexType>
</xs:element>
<xs:element name="Records" maxOccurs="unbounded" minOccurs="0" nillable="true">
<xs:annotation>
<xs:appinfo>
<b:recordInfo suppress_trailing_delimiters="false" preserve_delimiter_for_empty_data="true" sequence_number="2" structure="positional"/>
</xs:appinfo>
</xs:annotation>
<xs:complexType>
[...]
</xs:complexType>
</xs:element>
<xs:element name="Footers" maxOccurs="1" minOccurs="1">
<xs:annotation>
<xs:appinfo>
<b:recordInfo suppress_trailing_delimiters="false" preserve_delimiter_for_empty_data="true" sequence_number="3" structure="positional" tag_name="F" tag_offset="0"/>
</xs:appinfo>
</xs:annotation>
<xs:complexType>
[...]
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
Tried setting the records to minoccurrs = 0 and nillable, but error persists. How can I get the pipeline to handle a file with no records in this case?

If your lines do not have a tag, and you have other records following, then change the Schema properties, Parser Optimisation from Speed to Complexity.
The reason for this is because the line doesn't have a tag, it has trouble recognising when the lines end.
Setting it to Complexity does the following
In complexity mode, the flat file parsing engine uses both top-down and bottom-up parsing, and tries to fit data more accurately. In speed mode, the parser tries to fit data as they appear in the stream.
Parsing Modes (learn.microsoft.com).

Related

BizTalk Imports only one row from CSV file

My BizTalk orchestration imports only 1 row.
I cannot figure out what is wrong, since there are no error messages or warnings.
I am using:
WCF
Orchestration
Receive Pipeline
Stored Procedure
CSV Flat File
I think the issue is in the csv schema.
<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns="http://ElecFFILEImport.FFILECSVSchema" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" targetNamespace="http://ElecFFILEImport.FFILECSVSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:annotation>
<xs:appinfo>
<schemaEditorExtension:schemaInfo namespaceAlias="b" extensionClass="Microsoft.BizTalk.FlatFileExtension.FlatFileExtension" standardName="Flat File" xmlns:schemaEditorExtension="http://schemas.microsoft.com/BizTalk/2003/SchemaEditorExtensions" />
<b:schemaInfo standard="Flat File" codepage="65001" default_pad_char=" " pad_char_type="char" count_positions_by_byte="false" parser_optimization="speed" lookahead_depth="3" suppress_empty_nodes="false" generate_empty_nodes="true" allow_early_termination="true" early_terminate_optional_fields="false" allow_message_breakup_of_infix_root="false" compile_parse_tables="false" root_reference="FFILERoot" />
</xs:appinfo>
</xs:annotation>
<xs:element name="FFILERoot">
<xs:annotation>
<xs:appinfo>
<b:recordInfo structure="delimited" child_delimiter_type="hex" child_delimiter="0xD 0xA" child_order="postfix" sequence_number="1" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:annotation>
<xs:appinfo>
<groupInfo sequence_number="0" xmlns="http://schemas.microsoft.com/BizTalk/2003" />
</xs:appinfo>
</xs:annotation>
<xs:element name="Header">
<xs:annotation>
<xs:appinfo>
<b:recordInfo structure="delimited" child_delimiter_type="hex" child_delimiter="0xD 0xA" child_order="infix" sequence_number="1" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:annotation>
<xs:appinfo>
<groupInfo sequence_number="0" xmlns="http://schemas.microsoft.com/BizTalk/2003" />
</xs:appinfo>
</xs:annotation>
<xs:element name="Header_Row" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo justification="left" sequence_number="1" />
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element maxOccurs="unbounded" name="Detail">
<xs:annotation>
<xs:appinfo>
<b:recordInfo structure="delimited" child_delimiter_type="char" child_delimiter="," child_order="infix" sequence_number="2" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:annotation>
<xs:appinfo>
<groupInfo sequence_number="0" xmlns="http://schemas.microsoft.com/BizTalk/2003" />
</xs:appinfo>
</xs:annotation>
<xs:element name="FFILECompany" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo justification="left" sequence_number="1" />
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="AccountName" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo justification="left" sequence_number="2" />
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="HomeAddress" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo justification="left" sequence_number="3" />
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="AccountNumber" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo justification="left" sequence_number="4" />
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="ServiceNumber" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo justification="left" sequence_number="5" />
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="BNumber" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo justification="left" sequence_number="6" />
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="DS" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo justification="left" sequence_number="7" />
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="LPC" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo justification="left" sequence_number="8" />
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="RDate" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo justification="left" sequence_number="9" />
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="PDate" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo justification="left" sequence_number="10" />
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="BOption" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo justification="left" sequence_number="11" />
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="RSCode" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo justification="left" sequence_number="12" />
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="CPAssigment" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo justification="left" sequence_number="13" />
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="Status" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo justification="left" sequence_number="14" />
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
But just in case here is a sample file (fake data)
FFILECompany,Account Name,Home Address,Account Number,Service Number,Bill Number,Delivery Service,LPC,RDate,PDate,BOption,RSCode,CPAssignment,Status
Company A,NORM W MYERS,0 X WEST STREET STRONGHURST IL 61480,6996293052,439998937,5,DS1,DSHDHD-HP,2014-01-02,,BILL,,,ACTIVE
Company B,ROSABEL BLESKIN,982001 RUSTIC ST ROBINSON IL 62466,1499936152,53875283,13,DS1,RDDD-HP,2014-10-10,,BILL,,,ACTIVE
Company C,TIEE E DISNEY,140505 BEL AIRE DR BELLEVILLE IL 62299,1058999074,40564211,10,DS1,RESSS-HP,2015-01-11,2015-11-09,BILL,,,PENDING INACTIVE
Company D,STEVE BROWN,1044920 COLLEGE AVE ALTON IL 62154,1048999118,54999928,2,DS1,RSS-HP,2014-06-26,,BILL,,,ACTIVE
And finally, here is my stored procedure:
As you can see I only import a few columns:
CREATE PROCEDURE [dbo].[AccountImport]
#Commodity NVARCHAR(255) , -- Hard Coded value inside the map
#LDCCode NVARCHAR(2) , -- Hard Coded value inside the map
#AccountNumber NVARCHAR(255) ,
#AccountName NVARCHAR(255) ,
#HomeAddress NVARCHAR(255)
AS
INSERT INTO dbo.[CustomerTable]
( Commodity ,
LDCCode ,
AccountNumber ,
AccountName ,
HomeAddress
)
SELECT #Commodity ,
#LDCCode ,
#AccountNumber ,
#AccountName ,
#HomeAddress
DECLARE #MID AS INT
SELECT #MID = ##IDENTITY
--This stored procedure will parse the address and separate Address city and state using a space
EXEC [sync].[ParseAddress] #ID = #MID
Again, there are no errors, and one row is imported every time (the first row).
Make sure you set up your schema as an envelope schema to cater for multiple records. See the below links
https://msdn.microsoft.com/en-us/library/aa546772.aspx
http://www.codeproject.com/Articles/507336/Envelope-Schema-and-Debatching
How does the message that enter the orchestration look like? If it is only one row, then the problem is in receive pipeline; solution for that:
I think you should define two separate schemas, one for the header of the fileand one for the body of the csv file. Fill inf Flat File Disassembler pipeline like this:
DocumentSchema: BodySchemaName, AssemblyName
HeaderSchema: HeaderName, AssemblyName
If the message in the orchestration is full, without header, only body, then the problem is in the mapping, so you should provide us with more information. What does the schema you map into look like?
Make sure the "Max occurs" property on the record node of the inbound schema is set to "unbounded"

Developing a Custom Receive Pipeline with Flat File Disassembler

I have a .txt file which is in the similar format as below
1115151651515950000055 00012913702613000000000003000 139C0000007000000
1215151651121510000054 00022913803603000000000009000 000279A0000009000
1315115950000065516515 00032813104643000000000007000 000399B0000003000
121515160003290003290000010000000003000
The first 3 lines are body elements but the number of lines in the body part will be unknown(may occur from 1 to unbounded). There is no tag identifier in body part. The last line in the file is always a trailer.The trailer from the file is to be removed prior to parsing so that only the records need parsed. How can this be done using a Pipeline Component in the Flat File Disassembler.
You should not need to remove the trailer.
What you need it to define a Flat File Schema where the Body Record can occur unbounded and a separate record for the trailer.
You have to set the the delimiters on the Root in the example below, Child Delimiter = 0x0D 0x0A (CR LF), Child Delimiter Type = Hexadecimal, Child Order=Infix, but that may vary and you have to declare the correct delimiter and where the occur. For the above file I assumed that there was no CR LF after the trailer, hence chose Infix (delimiter occurs between) rather than Postfix (delimiter occurs after) if the last line does have a CR LF.
You can then define the Body and Trailer Structure to be either Delimited or Positional.
Update: To not have the trailer in the message to be processed, have a map on the receive port that only maps the Body records and not the trailer.
<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns="http://Scratch.FlatFile" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" targetNamespace="http://Scratch.FlatFile" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:annotation>
<xs:appinfo>
<b:schemaInfo standard="Flat File" root_reference="Root" default_pad_char=" " pad_char_type="char" count_positions_by_byte="false" parser_optimization="speed" lookahead_depth="3" suppress_empty_nodes="false" generate_empty_nodes="true" allow_early_termination="false" early_terminate_optional_fields="false" allow_message_breakup_of_infix_root="false" compile_parse_tables="false" />
<schemaEditorExtension:schemaInfo namespaceAlias="b" extensionClass="Microsoft.BizTalk.FlatFileExtension.FlatFileExtension" standardName="Flat File" xmlns:schemaEditorExtension="http://schemas.microsoft.com/BizTalk/2003/SchemaEditorExtensions" />
</xs:appinfo>
</xs:annotation>
<xs:element name="Root">
<xs:annotation>
<xs:appinfo>
<b:recordInfo structure="delimited" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" sequence_number="1" child_order="infix" child_delimiter_type="hex" child_delimiter="0x0D 0x0A" />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:annotation>
<xs:appinfo>
<b:groupInfo sequence_number="0" />
</xs:appinfo>
</xs:annotation>
<xs:element maxOccurs="unbounded" name="Body">
<xs:annotation>
<xs:appinfo>
<b:recordInfo sequence_number="1" structure="delimited" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:annotation>
<xs:appinfo>
<b:groupInfo sequence_number="0" />
</xs:appinfo>
</xs:annotation>
<xs:element name="BodyContents" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo sequence_number="1" justification="left" />
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Trailer">
<xs:annotation>
<xs:appinfo>
<b:recordInfo sequence_number="2" structure="delimited" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:annotation>
<xs:appinfo>
<b:groupInfo sequence_number="0" />
</xs:appinfo>
</xs:annotation>
<xs:element name="TrailerContents" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo sequence_number="1" justification="left" />
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

How to specify the Flat File Schema to handle random sequence of different line types?

I have a two types of flat file lines,
start with #, e.g. #111 222 333
start with #, e.g. #777 888 999
We can use tag identifier to identify these two types of lines. Unfortunately, these two lines may appear in any sequence in a file, like #####, or #####, or ##### etc.
If use flat file dissembler schema, seems the sequence must be in order, say #####, ###, it can disassemble all flat file content into XML format.
But if the file format is ###### or ######, it cannot dissemble all file content and will stop at the middle, say ###### can only disassemble ###, ###### can only disassemble ####.
I think it is because the flat file schema specify the sequence is # and then #, therefore, # cannot appear after # (please inform if my understanding is wrong).
Any solution to our case?
Thanks.
Put a the tagged records under a Choice Group that can occur multiple times.
See example below.
<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns="http://Scratch.FlatFileSchemaRandomTagOrder" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" targetNamespace="http://Scratch.FlatFileSchemaRandomTagOrder" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:annotation>
<xs:appinfo>
<b:schemaInfo standard="Flat File" root_reference="Root" default_pad_char=" " pad_char_type="char" count_positions_by_byte="false" parser_optimization="speed" lookahead_depth="3" suppress_empty_nodes="false" generate_empty_nodes="true" allow_early_termination="false" early_terminate_optional_fields="false" allow_message_breakup_of_infix_root="false" compile_parse_tables="false" />
<schemaEditorExtension:schemaInfo namespaceAlias="b" extensionClass="Microsoft.BizTalk.FlatFileExtension.FlatFileExtension" standardName="Flat File" xmlns:schemaEditorExtension="http://schemas.microsoft.com/BizTalk/2003/SchemaEditorExtensions" />
</xs:appinfo>
</xs:annotation>
<xs:element name="Root">
<xs:annotation>
<xs:appinfo>
<b:recordInfo structure="delimited" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" sequence_number="1" child_order="postfix" child_delimiter_type="hex" child_delimiter="0x0D 0x0A" />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:annotation>
<xs:appinfo>
<b:groupInfo sequence_number="0" />
</xs:appinfo>
</xs:annotation>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:annotation>
<xs:appinfo>
<b:groupInfo sequence_number="1" />
</xs:appinfo>
</xs:annotation>
<xs:element name="RecordHash">
<xs:annotation>
<xs:appinfo>
<b:recordInfo structure="delimited" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" sequence_number="1" tag_name="#" child_order="infix" child_delimiter_type="char" child_delimiter=" " />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:annotation>
<xs:appinfo>
<b:groupInfo sequence_number="0" />
</xs:appinfo>
</xs:annotation>
<xs:element name="Field1" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo sequence_number="1" justification="left" />
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="Field2" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo justification="left" sequence_number="2" />
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="Field3" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo justification="left" sequence_number="3" />
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="RecordAt">
<xs:annotation>
<xs:appinfo>
<b:recordInfo sequence_number="2" structure="delimited" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" tag_name="#" child_order="infix" child_delimiter_type="char" child_delimiter=" " />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:annotation>
<xs:appinfo>
<b:groupInfo sequence_number="0" />
</xs:appinfo>
</xs:annotation>
<xs:element name="Field1" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo sequence_number="1" justification="left" />
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="Field2" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo justification="left" sequence_number="2" />
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="Field3" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo justification="left" sequence_number="3" />
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Sample file
#111 222 333
#777 888 999
#111 222 333
Output
<Root xmlns="http://Scratch.FlatFileSchemaRandomTagOrder">
<RecordAt xmlns="">
<Field1>111</Field1>
<Field2>222</Field2>
<Field3>333</Field3>
</RecordAt>
<RecordHash xmlns="">
<Field1>777</Field1>
<Field2>888</Field2>
<Field3>999</Field3>
</RecordHash>
<RecordAt xmlns="">
<Field1>111</Field1>
<Field2>222</Field2>
<Field3>333</Field3>
</RecordAt>
</Root>

BizTalk flat file output schema - Test Map gives Output validation error: The element 'Root' has invalid child element 'Record'

I have a fairly simple flat file schema that just generates CSV, or at least it is supposed to. It has a Root node which is delimited by CRLF, and then a Record node which is delimited by comma, and then the actual fields under that.
<?xml version="1.0" encoding="utf-16" ?>
<xs:schema xmlns="http://My.Namespace" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" targetNamespace="http://My.Namespace" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:annotation>
<xs:appinfo>
<schemaEditorExtension:schemaInfo namespaceAlias="b" extensionClass="Microsoft.BizTalk.FlatFileExtension.FlatFileExtension" standardName="Flat File" xmlns:schemaEditorExtension="http://schemas.microsoft.com/BizTalk/2003/SchemaEditorExtensions" />
<b:schemaInfo standard="Flat File" codepage="65001" default_pad_char="" pad_char_type="char" count_positions_by_byte="false" parser_optimization="speed" lookahead_depth="3" suppress_empty_nodes="false" generate_empty_nodes="true" allow_early_termination="false" early_terminate_optional_fields="false" allow_message_breakup_of_infix_root="false" compile_parse_tables="false" root_reference="Root" />
</xs:appinfo>
</xs:annotation>
<xs:element name="Root">
<xs:annotation>
<xs:appinfo>
<b:recordInfo structure="delimited" child_delimiter_type="hex" child_delimiter="0xD 0xA" child_order="postfix" sequence_number="1" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:annotation>
<xs:appinfo>
<groupInfo sequence_number="0" xmlns="http://schemas.microsoft.com/BizTalk/2003" />
</xs:appinfo>
</xs:annotation>
<xs:element name="Record">
<xs:annotation>
<xs:appinfo>
<b:recordInfo structure="delimited" child_delimiter_type="char" child_delimiter="," child_order="infix" sequence_number="1" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:annotation>
<xs:appinfo>
<groupInfo sequence_number="0" xmlns="http://schemas.microsoft.com/BizTalk/2003" />
</xs:appinfo>
</xs:annotation>
<xs:element minOccurs="0" default="" name="TheFirstField" nillable="true" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo justification="left" sequence_number="1" />
</xs:appinfo>
</xs:annotation>
</xs:element>
<!-- And more fields here -->
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
When I do a Generate Instance on this schema, I get a file that just has commas, which suggests to me that it is at least somewhat set up right for creating CSV. However, when I have this schema as the output type of a map, from an input type of an XML file, and I do a Test Map, I get this:
Invoking component...
TestMap used the following file: <file:///C:\path\to\test.xml> as input to the map.
C:\path\to\output.xml: error btm1046: Output validation error: The element 'Root' in namespace 'http://My.Namespace' has invalid child element 'Record'.
Test Map failure for map file <file:///C:\path\to\my\Map.btm>. The output is stored in the following file: <file:///C:\path\to\output.txt>
Component invocation succeeded.
The output.txt file does not end up getting created.
What is the reason for this error when testing the map with a flat file output, and how do I resolve it?
This error indicates that the generated output from the map doesn't validate with your schema. I tried your example but it works on my machineā„¢. The schema you've provided does allow for the Record element to be a child of Root.
Can you see if the file C:\path\to\output.xml is being created and, if so, does it show the same error when validating against your schema? What happens when you set the Test Map Output to Native instead of XML? Can you also check if your assemblies are up to date in the Global Assembly Cache?

Biztalk schema variable number of columns in delimited file permitted?

Hiyas. I have a customer sending orders to us in a flat file. There isn't really any complexity to the file but there are some inconsistencies from file to file.
The format of the file is like this:
1,2,3[CRLF]
1,2,3[CRLF]
No problems creating a schema around that structure, however from time to time they will add a new column.
1,2,3,4[CRLF]
1,2,3,4[CRLF]
Unfortunatly, they don't make their changes cascade backwards so we hare expected to support both the 3 and 4 column formats. Both formats can potentially come through the same pipeline, so i don't really have the option of creating seperate schemas/pipelines. They do always add the new fields to the end of the row, so that much at least is consistent.
The only thiing i can think of to do is to create an elaborate "figure out which schema applies and route accordingly pipeline component", but before I go down that road I wanted to see if maybe anyone had some thoughts on way to make it work with a single flat file schema (I tried to set the minOccurs property of the optional columns to 0, but that was no good).
Thanks in advance for any advice.
One way would be to define a "outer" schema and import schemas for the different versions you need to support. The "outer" schema will offer a choice block containing references to your imported version schemas.
If you need to add the next version you just have to import a new schema and add it to the choice.
The hard part of course is how you can determine how to process different versions. Maybe the simplest way would be to create a map for every dedicated type you need to handle. On the other hand you could extend a "latest-and-greatest" internal message type and decide based on message content.
"outer" schema
<!-- language: xml-schema -->
<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns:ns0="http://ACME.Version_001" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" xmlns="http://ACME.Outer" xmlns:ns1="http://ACME.Version_002" targetNamespace="http://ACME.Outer" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import schemaLocation=".\version_002.xsd" namespace="http://ACME.Version_002" />
<xs:import schemaLocation=".\version_001.xsd" namespace="http://ACME.Version_001" />
<xs:annotation>
<xs:appinfo>
<b:schemaInfo standard="Flat File" root_reference="Root" />
<schemaEditorExtension:schemaInfo namespaceAlias="b" extensionClass="Microsoft.BizTalk.FlatFileExtension.FlatFileExtension" standardName="Flat File" xmlns:schemaEditorExtension="http://schemas.microsoft.com/BizTalk/2003/SchemaEditorExtensions" />
<b:references>
<b:reference targetNamespace="http://ACME.Version_001" />
<b:reference targetNamespace="http://ACME.Version_002" />
</b:references>
</xs:appinfo>
</xs:annotation>
<xs:element name="Root">
<xs:annotation>
<xs:appinfo>
<b:recordInfo structure="delimited" sequence_number="1" child_delimiter_type="hex" child_order="postfix" child_delimiter="0x0D 0x0A" />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:choice minOccurs="1">
<xs:element ref="ns0:Version_001">
<xs:annotation>
<xs:appinfo>
<b:recordInfo sequence_number="1" structure="delimited" />
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element ref="ns1:Version_002">
<xs:annotation>
<xs:appinfo>
<b:recordInfo sequence_number="2" structure="delimited" />
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Imported schema "Version_001"
<!-- language: xml-schema -->
<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns:b="http://schemas.microsoft.com/BizTalk/2003" xmlns="http://ACME.Version_001" targetNamespace="http://ACME.Version_001" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:annotation>
<xs:appinfo>
<b:schemaInfo standard="Flat File" root_reference="Version_001" />
<schemaEditorExtension:schemaInfo namespaceAlias="b" extensionClass="Microsoft.BizTalk.FlatFileExtension.FlatFileExtension" standardName="Flat File" xmlns:schemaEditorExtension="http://schemas.microsoft.com/BizTalk/2003/SchemaEditorExtensions" />
</xs:appinfo>
</xs:annotation>
<xs:element name="Version_001">
<xs:annotation>
<xs:appinfo>
<b:recordInfo structure="delimited" child_delimiter_type="char" child_order="infix" rootTypeName="Version_001" child_delimiter="," />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="Col1" type="xs:string" />
<xs:element name="Col2" type="xs:string" />
<xs:element name="Col3" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Imported schema "Version_002"
<!-- language: xml-schema -->
<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns:b="http://schemas.microsoft.com/BizTalk/2003" xmlns="http://ACME.Version_002" targetNamespace="http://ACME.Version_002" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:annotation>
<xs:appinfo>
<b:schemaInfo standard="Flat File" root_reference="Version_002" />
<schemaEditorExtension:schemaInfo namespaceAlias="b" extensionClass="Microsoft.BizTalk.FlatFileExtension.FlatFileExtension" standardName="Flat File" xmlns:schemaEditorExtension="http://schemas.microsoft.com/BizTalk/2003/SchemaEditorExtensions" />
</xs:appinfo>
</xs:annotation>
<xs:element name="Version_002">
<xs:annotation>
<xs:appinfo>
<b:recordInfo structure="delimited" child_delimiter_type="char" child_order="infix" rootTypeName="Version_001" child_delimiter="," />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="Col1" type="xs:string" />
<xs:element name="Col2" type="xs:string" />
<xs:element name="Col3" type="xs:string" />
<xs:element name="Col4" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
(some default attributes omitted for readability)

Resources