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)
Related
I have defined a schema with several promoted properties.
I have a two way send port that calls a rest service.
The rest service returns a response matching the message schema. The receive pipeline for the two way send port has an xml disassembler component in it.
I also have a two way receive port.
The receive pipeline of the receive port has a component that publishes multiple messages into the queue so they are available using the GetNext() function. One of the messages matches the schema I published. The next component in the pipeline is an xml disassembler component.
I would have thought that in both ports, because my receive port has an xml disassembler, it would publish the promoted properties of the message so that I can subscribe to them in send ports, The values are not being promoted and I don't know why that is.
Here is my message schema:
<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns="http://MyMessage" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" xmlns:ns0="https://MyMessageProperties.PropertySchema" targetNamespace="http://MyMessage" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:annotation>
<xs:appinfo>
<b:imports xmlns:b="http://schemas.microsoft.com/BizTalk/2003">
<b:namespace prefix="ns0" uri="https://MyMessageProperties.PropertySchema" location=".\PropertySchema.xsd" />
</b:imports>
</xs:appinfo>
</xs:annotation>
<xs:element name="MessageProcessingResult">
<xs:annotation>
<xs:appinfo>
<b:properties>
<b:property name="ns0:Category" xpath="/*[local-name()='MessageProcessingResult' and namespace-uri()='http://MyMessage']/*[local-name()='Category' and namespace-uri()='']" />
<b:property name="ns0:Code" xpath="/*[local-name()='MessageProcessingResult' and namespace-uri()='http://MyMessage']/*[local-name()='Code' and namespace-uri()='']" />
<b:property name="ns0:ComponentOfOrigin" xpath="/*[local-name()='MessageProcessingResult' and namespace-uri()='http://MyMessage']/*[local-name()='ComponentOfOrigin' and namespace-uri()='']" />
<b:property name="ns0:OriginalMessageTypeValue" xpath="/*[local-name()='MessageProcessingResult' and namespace-uri()='http://MyMessage']/*[local-name()='OriginalMessageType' and namespace-uri()='']/*[local-name()='Value' and namespace-uri()='']" />
<b:property name="ns0:OriginalMessageID" xpath="/*[local-name()='MessageProcessingResult' and namespace-uri()='http://MyMessage']/*[local-name()='OriginalMessageID' and namespace-uri()='']" />
</b:properties>
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:all>
<xs:element name="Category">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="Success" />
<xs:enumeration value="Problem" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="Code" type="xs:string" />
<xs:element name="ComponentOfOrigin" type="xs:string" />
<xs:element name="OriginalMessageID" type="xs:string" />
<xs:element name="OriginalMessageType" type="Type" />
</xs:all>
</xs:complexType>
</xs:element>
<xs:complexType name="Type">
<xs:all>
<xs:element minOccurs="1" maxOccurs="1" name="Value" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="Name" type="xs:string" />
</xs:all>
</xs:complexType>
</xs:schema>
Here is my property schema:
<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns="http://MyMessageProperties.PropertySchema" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" targetNamespace="https://MyMessageProperties.PropertySchema" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:annotation>
<xs:appinfo>
<b:schemaInfo schema_type="property" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" />
</xs:appinfo>
</xs:annotation>
<xs:element default="Problem" name="Category" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo propertyGuid="676ad92f-16de-42df-8758-6b92dc4816a6" />
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element default="Unkown" name="Code" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo propertyGuid="74bf0ac9-fe44-4ef1-a27c-64afe0e334bb" />
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element default="Unknown" name="ComponentOfOrigin" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo propertyGuid="860e8876-8a0e-4fbd-aebe-84ee12bfb041" />
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element default="00000000-0000-0000-0000-000000000000" name="OriginalMessageTypeValue" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo propertyGuid="4d329f1d-4944-46e0-9ec9-4b87eb8d7a71" />
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element default="00000000-0000-0000-0000-000000000000" name="OriginalMessageID" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo propertyGuid="5bc4a75a-8fb3-4b54-becc-89e5415d216d" />
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:schema>
The issue is that only ONE dissembler will execute.
Notice the graphics in the Disassemble stage vs the Decode stage.
The Decode components will fire in sequence, but the Disassemble stage will probe which component matches the message, and the first one that matches will fire, and only that one.
Pipelines (Microsoft)
As an example of execution modes, the Disassemble stage of a receive pipeline is a First Match stage, thus each component in the stage is called to see if it recognizes the message and can process it. If the component responds in the affirmative, then no other components in that stage are queried to see if they can also handle the message. However, the Decode stage of a receive pipeline has an execution mode of All, meaning that each component in this stage is called to process the message in the order in which they were configured. The first decoder might be to decrypt the message, while the second might be to decompress the message from a zipped format.
So if you want to promote properties and also de-batch, you need to do in both your custom Disassembler.
e.g.
outMsg.Context.Promote(Name, Namespace, PropertyValue);
I have a multipart message with this schema (edited for brevity):
<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns="http://MyCompany/Schemas/Canonical/Property/1.0" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" targetNamespace="http://MyCompany/Schemas/Canonical/Property/1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Property">
<xs:annotation>
<xs:appinfo>
<b:properties>
<b:property distinguished="true" xpath="/*[local-name()='Property' and namespace-uri()='http://MyCompany/Schemas/Canonical/Property/1.0']/*[local-name()='UPRN' and namespace-uri()='']" />
</b:properties>
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" name="Addresses">
<xs:complexType />
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="UPRN" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Given that the message name in an Orchestration is MyMessage, how would I access the value of the distinguished field 'UPRN' in a BizTalk Expression Editor.
When I try dot notation all I get from IntilliSense is MyMessage.Property
It's supposed to be:
MessageName.PartName.RootNode.ElememtName[...].FieldName
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>
I have a flatfile that looks something like the following:
brand: bmw {CR}{LF}
{CR}{LF}
engine: 2000cc {CR}{LF}
{CR}{LF}
description: bla bla{CR}{LF}
{CR}{LF}
bla bla bla{CR}{LF}
bla bla bla{CR}{LF}
{CR}{LF}
bla{CR}{LF}
{CR}{LF}
remarks: none
To delimiter brand, engine, description and remarks, i could use "{CR}{LF}{CR}{LF}", but since description is containing "{CR}{LF}{CR}{LF}" aswell, and it could be any number of rows in description.
I would like to get an xml like:
<brand>bmw</brand>
<engine>2000cc</engine>
<description>bla bla{CR}{LF}{CR}{LF}bla bla bla{CR}{LF}{CR}{LF}bla bla ....</description>
<remarks>none</remarks>
Is this possible with a flatfile schema?
You probably won't be able to preserve the CR LF in the description initially, however you could create a structure that would allow you to re-assemble it afterwards.
1) Use tags to identify those that have them including the first description line.
2) Have a repeating record without a tag for the subsequent Description lines.
3) You can then map the two sets of description lines together into your target schema using the Cumulative Concatenate and adding the line breaks back in.
See sample schema below.
<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns="http://Scratch.Car" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" targetNamespace="http://Scratch.Car" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:annotation>
<xs:appinfo>
<b:schemaInfo standard="Flat File" root_reference="Car" 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="Car">
<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 name="Brand">
<xs:annotation>
<xs:appinfo>
<b:recordInfo sequence_number="1" structure="delimited" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" tag_name="brand: " />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:annotation>
<xs:appinfo>
<b:groupInfo sequence_number="0" />
</xs:appinfo>
</xs:annotation>
<xs:element name="BrandName" 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="Empty1">
<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:element>
<xs:element name="Engine">
<xs:annotation>
<xs:appinfo>
<b:recordInfo structure="delimited" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" tag_name="engine: " sequence_number="3" />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:annotation>
<xs:appinfo>
<b:groupInfo sequence_number="0" />
</xs:appinfo>
</xs:annotation>
<xs:element name="EngineType" 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="Empty2">
<xs:annotation>
<xs:appinfo>
<b:recordInfo structure="delimited" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" sequence_number="4" />
</xs:appinfo>
</xs:annotation>
<xs:complexType />
</xs:element>
<xs:element name="Description">
<xs:annotation>
<xs:appinfo>
<b:recordInfo sequence_number="5" structure="delimited" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" tag_name="description:" />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:annotation>
<xs:appinfo>
<b:groupInfo sequence_number="0" />
</xs:appinfo>
</xs:annotation>
<xs:element name="DescriptionLine" 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="DescriptionCont">
<xs:annotation>
<xs:appinfo>
<b:recordInfo structure="delimited" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" sequence_number="6" />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:annotation>
<xs:appinfo>
<b:groupInfo sequence_number="0" />
</xs:appinfo>
</xs:annotation>
<xs:element name="DescriptionLine" 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="Remarks">
<xs:annotation>
<xs:appinfo>
<b:recordInfo sequence_number="7" structure="delimited" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" tag_name="remarks: " />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:annotation>
<xs:appinfo>
<b:groupInfo sequence_number="0" />
</xs:appinfo>
</xs:annotation>
<xs:element name="Remark" 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>
This gives you XML of
<?xml version="1.0"?>
<Car xmlns="http://Scratch.Car">
<Brand xmlns="">
<BrandName>bmw</BrandName>
</Brand>
<Empty1 xmlns=""/>
<Engine xmlns="">
<EngineType>2000cc</EngineType>
</Engine>
<Empty2 xmlns=""/>
<Description xmlns="">
<DescriptionLine> bla bla</DescriptionLine>
</Description>
<DescriptionCont xmlns="">
<DescriptionLine/>
</DescriptionCont>
<DescriptionCont xmlns="">
<DescriptionLine>bla bla bla</DescriptionLine>
</DescriptionCont>
<DescriptionCont xmlns="">
<DescriptionLine>bla bla bla</DescriptionLine>
</DescriptionCont>
<DescriptionCont xmlns="">
<DescriptionLine/>
</DescriptionCont>
<DescriptionCont xmlns="">
<DescriptionLine>bla</DescriptionLine>
</DescriptionCont>
<DescriptionCont xmlns="">
<DescriptionLine/>
</DescriptionCont>
<Remarks xmlns="">
<Remark>none</Remark>
</Remarks>
</Car>
Target schema
<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns:b="http://schemas.microsoft.com/BizTalk/2003" attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="car">
<xs:complexType>
<xs:sequence>
<xs:element name="brand" type="xs:string" />
<xs:element name="engine" type="xs:string" />
<xs:element name="description" type="xs:string" />
<xs:element name="remarks" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Map
And the output.
<car>
<brand>bmw</brand>
<engine>2000cc</engine>
<description>bla bla{CR}{LF}{CR}{LF}bla bla bla{CR}{LF}{CR}{LF}bla bla ....</description>
<remarks>none</remarks>
</car>
P.S. I put literal {CR}{LF} into the concatenate functoid rather than the CR & LF characters. To get the real ones use a scripting functoid that has return System.Environment.NewLine; that passed it to both concatenate functoids.
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?