2
votes

Given the pipe-delimited document:

HDR|A
PSN|CCC|111|00|111111111|DOE|JOHN||M
PSN|CCC|111|01|111111111|DOE|JANE|A|F|07/30/1975
ADR|CCC|111|00|U|100 S 1ST #11||ANYTOWN|US|XX|55555|09/24/2013|
PHN|CCC|111|00|U|US|5551111111||09/24/2013|

and the BizTalk schema:

<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns="http://xxxx.com/schemas/test1" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" targetNamespace="http://xxxx.com/schemas/test1" 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="complexity" lookahead_depth="0" suppress_empty_nodes="false" generate_empty_nodes="true" allow_early_termination="true" early_terminate_optional_fields="true" 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_order="postfix" sequence_number="1" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="true" child_delimiter="0x0D 0x0A" />
      </xs:appinfo>
    </xs:annotation>
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:annotation>
          <xs:appinfo>
            <groupInfo sequence_number="0" xmlns="http://schemas.microsoft.com/BizTalk/2003" />
          </xs:appinfo>
        </xs:annotation>
        <xs:element minOccurs="1" maxOccurs="1" name="Header" type="HeaderType">
          <xs:annotation>
            <xs:appinfo>
              <b:recordInfo structure="delimited" child_delimiter_type="char" child_delimiter="|" child_order="infix" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" tag_name="HDR" tag_offset="0" sequence_number="1" />
            </xs:appinfo>
          </xs:annotation>
        </xs:element>
        <xs:element minOccurs="0" maxOccurs="unbounded" name="Person" type="PersonType">
          <xs:annotation>
            <xs:appinfo>
              <b:recordInfo structure="delimited" tag_name="PSN" tag_offset="0" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" child_delimiter_type="char" child_delimiter="|" sequence_number="2" />
            </xs:appinfo>
          </xs:annotation>
        </xs:element>
        <xs:element minOccurs="0" maxOccurs="unbounded" name="Address" type="AddressType">
          <xs:annotation>
            <xs:appinfo>
              <b:recordInfo structure="delimited" tag_name="ADR" tag_offset="0" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" child_delimiter_type="char" child_delimiter="|" sequence_number="3" />
            </xs:appinfo>
          </xs:annotation>
        </xs:element>
        <xs:element minOccurs="0" maxOccurs="unbounded" name="Phone" type="PhoneType">
          <xs:annotation>
            <xs:appinfo>
              <b:recordInfo structure="delimited" tag_name="PHN" tag_offset="0" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" child_delimiter_type="char" child_delimiter="|" sequence_number="4" />
            </xs:appinfo>
          </xs:annotation>
        </xs:element>
      </xs:choice>
    </xs:complexType>
  </xs:element>
  <xs:complexType name="HeaderType">
    <xs:attribute default="" name="type" type="xs:string">
      <xs:annotation>
        <xs:appinfo>
          <b:fieldInfo justification="left" sequence_number="1" />
        </xs:appinfo>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute default="" name="description" type="xs:string">
      <xs:annotation>
        <xs:appinfo>
          <b:fieldInfo justification="left" sequence_number="2" />
        </xs:appinfo>
      </xs:annotation>
    </xs:attribute>
  </xs:complexType>
  <xs:complexType name="PersonType">
    <xs:attribute name="group" type="xs:string">
      <xs:annotation>
        <xs:appinfo>
          <b:fieldInfo justification="left" sequence_number="1" />
        </xs:appinfo>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute name="id" type="xs:string">
      <xs:annotation>
        <xs:appinfo>
          <b:fieldInfo justification="left" sequence_number="2" />
        </xs:appinfo>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute name="seq" type="xs:string">
      <xs:annotation>
        <xs:appinfo>
          <b:fieldInfo justification="left" sequence_number="3" />
        </xs:appinfo>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute default="" name="ssn" type="xs:string">
      <xs:annotation>
        <xs:appinfo>
          <b:fieldInfo justification="left" sequence_number="4" />
        </xs:appinfo>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute name="last" type="xs:string">
      <xs:annotation>
        <xs:appinfo>
          <b:fieldInfo justification="left" sequence_number="5" />
        </xs:appinfo>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute name="first" type="xs:string">
      <xs:annotation>
        <xs:appinfo>
          <b:fieldInfo justification="left" sequence_number="6" />
        </xs:appinfo>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute default="" name="mi" type="xs:string">
      <xs:annotation>
        <xs:appinfo>
          <b:fieldInfo justification="left" sequence_number="7" />
        </xs:appinfo>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute default="" name="gender" type="xs:string">
      <xs:annotation>
        <xs:appinfo>
          <b:fieldInfo justification="left" sequence_number="8" />
        </xs:appinfo>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute default="" name="dob" type="xs:string">
      <xs:annotation>
        <xs:appinfo>
          <b:fieldInfo justification="left" sequence_number="9" />
        </xs:appinfo>
      </xs:annotation>
    </xs:attribute>
  </xs:complexType>
  <xs:complexType name="AddressType">
    <xs:attribute name="group" type="xs:string">
      <xs:annotation>
        <xs:appinfo>
          <b:fieldInfo justification="left" sequence_number="1" />
        </xs:appinfo>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute name="id" type="xs:string">
      <xs:annotation>
        <xs:appinfo>
          <b:fieldInfo justification="left" sequence_number="2" />
        </xs:appinfo>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute name="seq" type="xs:string">
      <xs:annotation>
        <xs:appinfo>
          <b:fieldInfo justification="left" sequence_number="3" />
        </xs:appinfo>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute name="type" type="xs:string">
      <xs:annotation>
        <xs:appinfo>
          <b:fieldInfo justification="left" sequence_number="4" />
        </xs:appinfo>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute default="" name="addr1" type="xs:string">
      <xs:annotation>
        <xs:appinfo>
          <b:fieldInfo justification="left" sequence_number="5" />
        </xs:appinfo>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute default="" name="addr2" type="xs:string">
      <xs:annotation>
        <xs:appinfo>
          <b:fieldInfo justification="left" sequence_number="6" />
        </xs:appinfo>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute default="" name="city" type="xs:string">
      <xs:annotation>
        <xs:appinfo>
          <b:fieldInfo justification="left" sequence_number="7" />
        </xs:appinfo>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute default="" name="country" type="xs:string">
      <xs:annotation>
        <xs:appinfo>
          <b:fieldInfo justification="left" sequence_number="8" />
        </xs:appinfo>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute default="" name="state" type="xs:string">
      <xs:annotation>
        <xs:appinfo>
          <b:fieldInfo justification="left" sequence_number="9" />
        </xs:appinfo>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute default="" name="zip" type="xs:string">
      <xs:annotation>
        <xs:appinfo>
          <b:fieldInfo justification="left" sequence_number="10" />
        </xs:appinfo>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute name="date" type="xs:string">
      <xs:annotation>
        <xs:appinfo>
          <b:fieldInfo justification="left" sequence_number="11" />
        </xs:appinfo>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute default="" name="filler" type="xs:string">
      <xs:annotation>
        <xs:appinfo>
          <b:fieldInfo justification="left" sequence_number="12" />
        </xs:appinfo>
      </xs:annotation>
    </xs:attribute>
  </xs:complexType>
  <xs:complexType name="PhoneType">
    <xs:attribute name="client_code" type="xs:string">
      <xs:annotation>
        <xs:appinfo>
          <b:fieldInfo justification="left" sequence_number="1" />
        </xs:appinfo>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute name="id" type="xs:string">
      <xs:annotation>
        <xs:appinfo>
          <b:fieldInfo justification="left" sequence_number="2" />
        </xs:appinfo>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute name="seq" type="xs:string">
      <xs:annotation>
        <xs:appinfo>
          <b:fieldInfo justification="left" sequence_number="3" />
        </xs:appinfo>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute name="type" type="xs:string">
      <xs:annotation>
        <xs:appinfo>
          <b:fieldInfo justification="left" sequence_number="4" />
        </xs:appinfo>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute default="" name="country" type="xs:string">
      <xs:annotation>
        <xs:appinfo>
          <b:fieldInfo justification="left" sequence_number="5" />
        </xs:appinfo>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute default="" name="number" type="xs:string">
      <xs:annotation>
        <xs:appinfo>
          <b:fieldInfo justification="left" sequence_number="6" />
        </xs:appinfo>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute default="" name="extension" type="xs:string">
      <xs:annotation>
        <xs:appinfo>
          <b:fieldInfo justification="left" sequence_number="7" />
        </xs:appinfo>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute default="" name="date" type="xs:string">
      <xs:annotation>
        <xs:appinfo>
          <b:fieldInfo justification="left" sequence_number="8" />
        </xs:appinfo>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute default="" name="filler" type="xs:string">
      <xs:annotation>
        <xs:appinfo>
          <b:fieldInfo justification="left" sequence_number="9" />
        </xs:appinfo>
      </xs:annotation>
    </xs:attribute>
  </xs:complexType>
</xs:schema>

where "choice" is used on the Root (since the child records may be in any order), and where "tag_name" is used to match records to schema elements.

and running through the fadsm utility

ffdasm "test1.psv" -bs "test1.xsd" -s -m "test1.xml" -v -s

to get this

- <Root xmlns="http://xxxx.com/schemas/test1">
  <Header type="" description="A" xmlns="" /> 
  <Person group="CCC" id="111" seq="00" ssn="111111111" last="DOE" first="JOHN" mi="" gender="M PSN" dob="CCC|111|01|111111111|DOE|JANE|A|F|07/30/1975" xmlns="" /> 
  <Address group="CCC" id="111" seq="00" type="U" addr1="100 S 1ST #11" addr2="" city="ANYTOWN" country="US" state="XX" zip="55555" date="09/24/2013" filler="" xmlns="" /> 
  <Phone client_code="CCC" id="111" seq="00" type="U" country="US" number="5551111111" extension="" date="09/24/2013" filler="" xmlns="" /> 
  </Root>
  • Why is the header (HDR) record's first field value ("A") going into the wrong (second) attribute of the output XML?

  • Why is the record delimiter (CRLF / 0x0D ox0A) getting ignored such that second (PSN) record's contents go into optional attributes of the prior record in the resultant XML when the schema is set up for early termination of records and optional fields?

and BTW

  • Why does the "tag_name" matched content get omitted from the output XML for delimited files? This does not happen with fixed length flat files; in those, the tag_name data is retained in the output.

Any insight is much appreciated.

1

1 Answers

1
votes

The first field in the HDR is going to the second field due to the child_order you've defined of Infix. There are three child order, Prefix, Infix, Postfix.

Prefix means that the delimiter occurs before each field. |1|2|3

Infix means it occurs between each field. 1|2|3

Postfix means it occurs after each field. 1|2|3|

Now you have selected Infix. So lets look at your line.

HDR|A

You've told it that the tag is HDR, so it strips that of and is left with

|A

As it is infix, what is before the | is field 1, and after is field 2.

What you want is Prefix.

As you have observed the tag names get stripped out, they are treated as being the record name.

As for the record delimiter getting ignored, that is a bad habit of the flat file dissembler if it does expect another field that it doesn't find, and then it consumes the next line to make it into that field. Again check what type of child order you are doing and if the fields match up correctly.