我正在 BizTalk 2013 中开发用于平面文件反汇编的架构。但是,我的架构存在很大问题,因为解析结果很垃圾。我正在解析的平面文件类型如下所示:
HEADER:opt1:opt2:opt3+opt4:opt5+opt6+op7:opt8:opt9'
TAG1:opt1:opt2:opt3+opt4:opt5:opt6+op7:opt8:opt9'
TAG2:opt1:opt2:opt3+opt4:opt5:opt6+op7:opt8:opt9'
TAG3:opt1:opt2:opt3+opt4++opt6+op7:opt8:opt9'
TAG4:opt1:opt2:opt3+opt4:opt5'
平面文件具有三个层次结构部分:
顶级:Segments,由 ' 字符分隔(不是换行符,这只是为了提高可读性而添加的)
中级:Fields,由 + 字符分隔。可能直接包含一个值或一组值(见底层)
底层:属性,由:字符分隔
自从TAG? - 段是部分可选的,可能以多个顺序出现,我正在使用 parser_optimization="complexity" 选项和 lookahead_depth="0" 并使用TAG?-Name 来识别段类型,我用来解析所有内容。所有的分隔符都是 child_order="infix",除了段,它是 child_order="postfix"。
某些段、字段和属性是必需的,大多数不是。但是,第一个字段及其属性(标签名称,...)始终是必需的。段的分离和识别工作正常,字段也正常工作。但是,当我有包含一组可选属性的可选字段时,架构无法正确解析。示例: 语法:
TAGX:opt1:opt2:opt3+a1:a2:a3:a4:a5:a6'
都一个?属性是可选的
在解析这样的段时,属性值被放入正确的 XML 字段中:
TAGX:1:2:3+:1:2:::'
但是,由于平面文件规范允许省略可选字段,因此消息也可能如下所示:
TAGX:1:2:3+:1:2'
在这种情况下,值没有像应有的那样放入第二个和第三个 XML 字段,而是放入第三个和第四个。根据我在段中包含的 : 符号的数量,也可以填充第一个和第六个或第二个和第四个 XML 字段。
我需要平面文件解析器从左到右填充这些字段,而不是现在使用的混乱方式。但是,切换到 parser_optimization="speed" 不是一种选择,因为模式的其余部分太复杂了(除非有一种方法可以在本地执行此操作)。
这些是用于解析此类字段的 XSD 架构部分(仅提取的部分,因为架构非常大)
公共部分定义(包含在架构本身中,也被其他架构使用,在本示例中,它是一个 4 部分属性组):
<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns:b="http://schemas.microsoft.com/BizTalk/2003" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<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 root_reference="SEG_HEAD" pad_char_type="none" 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" standard="Flat File" default_pad_char=" "/>
</xs:appinfo>
</xs:annotation>
<xs:element name="MATERIAL_TYPE" type="MATERIAL_TYPE">
<xs:annotation>
<xs:appinfo>
<b:recordInfo sequence_number="4" structure="delimited" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" child_delimiter_type="char" child_delimiter=":" escape_char_type="char" escape_char="?" child_order="infix"/>
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:complexType name="MATERIAL_TYPE">
<xs:sequence>
<xs:annotation>
<xs:appinfo>
<b:groupInfo sequence_number="0"/>
</xs:appinfo>
</xs:annotation>
<xs:element name="NUMBER_SYSTEM" type="xs:string" minOccurs="0">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo sequence_number="1" justification="left"/>
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="MATERIAL" type="xs:string" minOccurs="0">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo sequence_number="2" justification="left"/>
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="EAN" type="xs:string" minOccurs="0">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo sequence_number="3" justification="left"/>
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="BUYERARTICLENUMBER" type="xs:string" minOccurs="0">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo sequence_number="4" justification="left"/>
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>
具体架构提取:
<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns="http://example.com/namespace" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://example.com/namespace" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:include schemaLocation=".\COMMON_SChema_v2.0.xsd"/>
<xs:annotation>
<xs:appinfo>
<b:schemaInfo standard="Flat File" root_reference="SEG_ORDER" pad_char_type="none" count_positions_by_byte="false" parser_optimization="complexity" lookahead_depth="0" suppress_empty_nodes="true" generate_empty_nodes="true" allow_early_termination="false" early_terminate_optional_fields="false" allow_message_breakup_of_infix_root="false" compile_parse_tables="false" default_pad_char=" " escape_char_type="char" default_escape_char="?" default_child_order="infix"/>
<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="SEG_ORDER">
<xs:annotation>
<xs:appinfo>
<b:recordInfo structure="delimited" child_order="postfix" escape_char_type="char" escape_char="?" sequence_number="17" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" 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="TAGX" maxOccurs="unbounded">
<xs:annotation>
<xs:appinfo>
<b:recordInfo structure="delimited" child_delimiter_type="char" child_delimiter="+" child_order="infix" escape_char_type="char" escape_char="?" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" sequence_number="6" tag_name="TAGX"/>
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:annotation>
<xs:appinfo>
<b:groupInfo sequence_number="0"/>
</xs:appinfo>
</xs:annotation>
<xs:element name="SEG_HEAD" type="SEG_HEAD_REF1_TYPE">
<xs:annotation>
<xs:appinfo>
<b:recordInfo structure="delimited" child_delimiter_type="char" child_delimiter=":" escape_char_type="char" escape_char="?" sequence_number="1" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" child_order="prefix"/>
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="POSITION_NUMBER">
<xs:annotation>
<xs:appinfo>
<b:recordInfo structure="delimited" child_delimiter_type="char" child_delimiter=":" child_order="infix" escape_char_type="char" escape_char="?" 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>
<b:groupInfo sequence_number="0"/>
</xs:appinfo>
</xs:annotation>
<xs:element name="NUMBER" 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 name="MATERIAL" type="MATERIAL_TYPE" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:appinfo>
<b:recordInfo structure="delimited" child_delimiter_type="char" child_delimiter=":" child_order="infix" escape_char_type="char" escape_char="?" sequence_number="3" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false"/>
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>