【问题标题】:How to create flat file XSD-schema for two level hierarchical data?如何为两级分层数据创建平面文件 XSD 模式?
【发布时间】:2018-02-27 07:20:31
【问题描述】:

我是 BizTalk 的新手,我必须从 CSV 文件创建 XSD 架构:

如您所见,它包括标题和订单。每个订单都有自己的订单标题 - 带有商店名称的行并填充了 Period 字段,但 QuantityPriceCostCurrency 字段为空。每个订单都有几个仓位,除了Period 之外的所有字段都填满了。每个订单头都有ItemNumber = 0。在这种情况下如何创建正确的平面文件架构?

OrderDate;OrderNumber;ItemNumber;DESCRIPTION_LONG;Quantity;Price;Cost;Period;Currency
30-04-17;9;0;Shop: McDonalds;;;;2017-04;
30-04-17;9;1;Double burger;2;5,99;11,98;;USD
30-04-17;9;2;Coca-Cola;2;2,19;4,38;;USD
30-04-17;10;0;Shop: Hunting and fishing;;;;2017-04;
30-04-17;10;1;Fishing rod;2;10,90;21,80;;USD
30-04-17;10;2;Bait;5;1,00;5,00;;USD
30-04-17;10;3;Hunting gun;1;999,00;999,00;;USD

【问题讨论】:

    标签: xsd biztalk flat-file


    【解决方案1】:

    您也许可以使用标签标识符来执行此操作(例如,请参阅 https://blogs.msdn.microsoft.com/biztalknotes/2013/02/05/flat-file-schema-creation-with-tag-identifiers-in-the-input-flat-file-repeating-in-a-random-fashion/),但我不能 100% 确定这会正常工作,因为标识符 (ItemNumber = 0) 不在开头的线。我的经验表明,在这些情况下,平面文件反汇编程序探测的成功有限。

    在这种情况下,我对人们的一般建议是不要尝试在您的平面文件架构中“强制”结构,因为显然您的平面文件结构没有它。我看到的是每一行都有相同的结构/格式。只是功能不同而已。

    从这个角度来看,我会选择一个与您的 CSV 文件结构匹配的平面文件模式(一种类型的记录,带有逗号分隔的字段和换行符作为行分隔符),然后从那里映射到一个模式在功能上更有意义。

    【讨论】:

    • 实际上它可以工作,因为项目的行已填充 Currency 字段,标题的行 - 还没有。当我创建平面文件架构时,BizTalk 认为这些行具有不同的字段数。但问题是我的平面文件有一个标题,这会破坏你创建平面文件模式的算法。如何在管道转换开始之前删除文件的第一行?或者我如何指定架构以跳过第一行?
    • 哦,不。 “不同字段计数”仅在创建模式期间有效。在工作中它显示正确的结果(相同数量的字段)
    【解决方案2】:

    我认为最好的选择是将您的平面文件解析为 XML,而无需尝试“强制”最终结构,正如 Pieter 在回答之前所说的那样。像这样的:

    <Root xmlns="http://BizTalkMassCopy.FlatFileSchema3">
      <Header xmlns="">
        <HeaderOrderDate>OrderDate</HeaderOrderDate>
        <HeaderOrderNumber>OrderNumber</HeaderOrderNumber>
        <HeaderItemNumber>ItemNumber</HeaderItemNumber>
        <HeaderDescription>DESCRIPTION_LONG</HeaderDescription>
        <HeaderQuantity>Quantity</HeaderQuantity>
        <HeaderPrice>Price</HeaderPrice>
        <HeaderCost>Cost</HeaderCost>
        <HeaderPeriod>Period</HeaderPeriod>
        <HeaderCurrency>Currency</HeaderCurrency>
      </Header>
      <OrderItem xmlns="">
        <OrderDate>30-04-17</OrderDate>
        <OrderNumber>9</OrderNumber>
        <ItemNumber>0</ItemNumber>
        <Description>Shop: McDonalds</Description>
        <Quantity></Quantity>
        <Price></Price>
        <Cost></Cost>
        <Period>2017-04</Period>
        <Currency></Currency>
      </OrderItem>
      <OrderItem xmlns="">
        <OrderDate>30-04-17</OrderDate>
        <OrderNumber>9</OrderNumber>
        <ItemNumber>1</ItemNumber>
        <Description>Double burger</Description>
        <Quantity>2</Quantity>
        <Price>5,99</Price>
        <Cost>11,98</Cost>
        <Period></Period>
        <Currency>USD</Currency>
      </OrderItem>
      <OrderItem xmlns="">
        <OrderDate>30-04-17</OrderDate>
        <OrderNumber>9</OrderNumber>
        <ItemNumber>2</ItemNumber>
        <Description>Coca-Cola</Description>
        <Quantity>2</Quantity>
        <Price>2,19</Price>
        <Cost>4,38</Cost>
        <Period></Period>
        <Currency>USD</Currency>
      </OrderItem>
      <OrderItem xmlns="">
        <OrderDate>30-04-17</OrderDate>
        <OrderNumber>10</OrderNumber>
        <ItemNumber>0</ItemNumber>
        <Description>Shop: Hunting and fishing</Description>
        <Quantity></Quantity>
        <Price></Price>
        <Cost></Cost>
        <Period>2017-04</Period>
        <Currency></Currency>
      </OrderItem>
      <OrderItem xmlns="">
        <OrderDate>30-04-17</OrderDate>
        <OrderNumber>10</OrderNumber>
        <ItemNumber>1</ItemNumber>
        <Description>Fishing rod</Description>
        <Quantity>2</Quantity>
        <Price>10,90</Price>
        <Cost>21,80</Cost>
        <Period></Period>
        <Currency>USD</Currency>
      </OrderItem>
      <OrderItem xmlns="">
        <OrderDate>30-04-17</OrderDate>
        <OrderNumber>10</OrderNumber>
        <ItemNumber>2</ItemNumber>
        <Description>Bait</Description>
        <Quantity>5</Quantity>
        <Price>1,00</Price>
        <Cost>5,00</Cost>
        <Period></Period>
        <Currency>USD</Currency>
      </OrderItem>
      <OrderItem xmlns="">
        <OrderDate>30-04-17</OrderDate>
        <OrderNumber>10</OrderNumber>
        <ItemNumber>3</ItemNumber>
        <Description>Hunting gun</Description>
        <Quantity>1</Quantity>
        <Price>999,00</Price>
        <Cost>999,00</Cost>
        <Period></Period>
        <Currency>USD</Currency>
      </OrderItem>
    </Root>
    

    使用与此类似的平面架构:

    <?xml version="1.0" encoding="utf-16"?>
    <xs:schema xmlns:b="http://schemas.microsoft.com/BizTalk/2003" xmlns="http://BizTalkMassCopy.FlatFileSchema3" targetNamespace="http://BizTalkMassCopy.FlatFileSchema3" 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="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">
              <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 name="HeaderOrderDate" type="xs:string">
                    <xs:annotation>
                      <xs:appinfo>
                        <b:fieldInfo justification="left" sequence_number="1" />
                      </xs:appinfo>
                    </xs:annotation>
                  </xs:element>
                  <xs:element name="HeaderOrderNumber" type="xs:string">
                    <xs:annotation>
                      <xs:appinfo>
                        <b:fieldInfo justification="left" sequence_number="2" />
                      </xs:appinfo>
                    </xs:annotation>
                  </xs:element>
                  <xs:element name="HeaderItemNumber" type="xs:string">
                    <xs:annotation>
                      <xs:appinfo>
                        <b:fieldInfo justification="left" sequence_number="3" />
                      </xs:appinfo>
                    </xs:annotation>
                  </xs:element>
                  <xs:element name="HeaderDescription" type="xs:string">
                    <xs:annotation>
                      <xs:appinfo>
                        <b:fieldInfo justification="left" sequence_number="4" />
                      </xs:appinfo>
                    </xs:annotation>
                  </xs:element>
                  <xs:element name="HeaderQuantity" type="xs:string">
                    <xs:annotation>
                      <xs:appinfo>
                        <b:fieldInfo justification="left" sequence_number="5" />
                      </xs:appinfo>
                    </xs:annotation>
                  </xs:element>
                  <xs:element name="HeaderPrice" type="xs:string">
                    <xs:annotation>
                      <xs:appinfo>
                        <b:fieldInfo justification="left" sequence_number="6" />
                      </xs:appinfo>
                    </xs:annotation>
                  </xs:element>
                  <xs:element name="HeaderCost" type="xs:string">
                    <xs:annotation>
                      <xs:appinfo>
                        <b:fieldInfo justification="left" sequence_number="7" />
                      </xs:appinfo>
                    </xs:annotation>
                  </xs:element>
                  <xs:element name="HeaderPeriod" type="xs:string">
                    <xs:annotation>
                      <xs:appinfo>
                        <b:fieldInfo justification="left" sequence_number="8" />
                      </xs:appinfo>
                    </xs:annotation>
                  </xs:element>
                  <xs:element name="HeaderCurrency" type="xs:string">
                    <xs:annotation>
                      <xs:appinfo>
                        <b:fieldInfo justification="left" sequence_number="9" />
                      </xs:appinfo>
                    </xs:annotation>
                  </xs:element>
                </xs:sequence>
              </xs:complexType>
            </xs:element>
            <xs:element maxOccurs="unbounded" name="OrderItem">
              <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="OrderDate" type="xs:string">
                    <xs:annotation>
                      <xs:appinfo>
                        <b:fieldInfo justification="left" sequence_number="1" />
                      </xs:appinfo>
                    </xs:annotation>
                  </xs:element>
                  <xs:element name="OrderNumber" type="xs:string">
                    <xs:annotation>
                      <xs:appinfo>
                        <b:fieldInfo justification="left" sequence_number="2" />
                      </xs:appinfo>
                    </xs:annotation>
                  </xs:element>
                  <xs:element name="ItemNumber" type="xs:string">
                    <xs:annotation>
                      <xs:appinfo>
                        <b:fieldInfo justification="left" sequence_number="3" />
                      </xs:appinfo>
                    </xs:annotation>
                  </xs:element>
                  <xs:element name="Description" type="xs:string">
                    <xs:annotation>
                      <xs:appinfo>
                        <b:fieldInfo justification="left" sequence_number="4" />
                      </xs:appinfo>
                    </xs:annotation>
                  </xs:element>
                  <xs:element name="Quantity" type="xs:string">
                    <xs:annotation>
                      <xs:appinfo>
                        <b:fieldInfo justification="left" sequence_number="5" />
                      </xs:appinfo>
                    </xs:annotation>
                  </xs:element>
                  <xs:element name="Price" type="xs:string">
                    <xs:annotation>
                      <xs:appinfo>
                        <b:fieldInfo justification="left" sequence_number="6" />
                      </xs:appinfo>
                    </xs:annotation>
                  </xs:element>
                  <xs:element name="Cost" type="xs:string">
                    <xs:annotation>
                      <xs:appinfo>
                        <b:fieldInfo justification="left" sequence_number="7" />
                      </xs:appinfo>
                    </xs:annotation>
                  </xs:element>
                  <xs:element name="Period" type="xs:string">
                    <xs:annotation>
                      <xs:appinfo>
                        <b:fieldInfo justification="left" sequence_number="8" />
                      </xs:appinfo>
                    </xs:annotation>
                  </xs:element>
                  <xs:element name="Currency" type="xs:string">
                    <xs:annotation>
                      <xs:appinfo>
                        <fieldInfo sequence_number="9" justification="left" xmlns="http://schemas.microsoft.com/BizTalk/2003" />
                      </xs:appinfo>
                    </xs:annotation>
                  </xs:element>
                </xs:sequence>
              </xs:complexType>
            </xs:element>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:schema>
    

    然后使用map得到最终结果,有Grouping in Biztalk Map Based on Multiple Elements等分组机制

    【讨论】:

    • 结果格式是正确的,但是传入的格式和我的完全不同。我是 BizTalk 的新手,我不擅长转型
    【解决方案3】:

    我的解决方案是,

    1. 创建用于解析平面文件的源架构。

    2. 为分组结果创建目标架构

    3. 为您的源架构分组创建一个映射。

    1. 将此内联 XSLT 脚本添加到您的地图中

    对于第一个脚本functoid

    <xsl:key name="groups" match="Order" use="OrderNumber"/>
    

    对于第二个脚本functoid

    <xsl:for-each select="Order[generate-id(.)=generate-id(key('groups',OrderNumber))]">
       <xsl:sort select="OrderNumber" order="ascending"/>
          <xsl:choose>
             <xsl:when test="OrderDate != 'OrderDate'">
                <Order>
                   <OrderDate><xsl:value-of select="OrderDate/text()" /></OrderDate>
                   <OrderNumber><xsl:value-of select="OrderNumber/text()" /></OrderNumber>
                   <Description><xsl:value-of select="Description/text()" /></Description>
                   <Period><xsl:value-of select="Period/text()" /></Period>
                   <Items>
                      <xsl:for-each select="key('groups',OrderNumber)">
                         <xsl:choose>
                            <xsl:when test="ItemNumber > '0'">
                               <Item>
                                  <ItemNumber><xsl:value-of select="ItemNumber" /></ItemNumber>
                                  <Quantity><xsl:value-of select="Quantity" /></Quantity>
                                  <Price><xsl:value-of select="Price" /></Price>
                                  <Cost><xsl:value-of select="Cost" /></Cost>
                                  <Currency><xsl:value-of select="Currency" /></Currency>
                               </Item>
                            </xsl:when>
                         </xsl:choose>
                      </xsl:for-each>
                   </Items>
                </Order>
             </xsl:when>
          </xsl:choose>   
    </xsl:for-each>
    
    1. 测试您的地图并获得此输出。
    <ns0:Orders xmlns:ns0="http://BizTalkServerTestProject.FlatFileSchema6">
      <Order>
        <OrderDate>30-04-17</OrderDate>
        <OrderNumber>10</OrderNumber>
        <Description>Shop: Hunting and fishing</Description>
        <Period>2017-04</Period>
        <Items>
          <Item>
            <ItemNumber>1</ItemNumber>
            <Quantity>2</Quantity>
            <Price>10,90</Price>
            <Cost>21,80</Cost>
            <Currency>USD</Currency>
          </Item>
          <Item>
            <ItemNumber>2</ItemNumber>
            <Quantity>5</Quantity>
            <Price>1,00</Price>
            <Cost>5,00</Cost>
            <Currency>USD</Currency>
          </Item>
          <Item>
            <ItemNumber>3</ItemNumber>
            <Quantity>1</Quantity>
            <Price>999,00</Price>
            <Cost>999,00</Cost>
            <Currency>USD</Currency>
          </Item>
        </Items>
      </Order>
      <Order>
        <OrderDate>30-04-17</OrderDate>
        <OrderNumber>9</OrderNumber>
        <Description>Shop: McDonalds</Description>
        <Period>2017-04</Period>
        <Items>
          <Item>
            <ItemNumber>1</ItemNumber>
            <Quantity>2</Quantity>
            <Price>5,99</Price>
            <Cost>11,98</Cost>
            <Currency>USD</Currency>
          </Item>
          <Item>
            <ItemNumber>2</ItemNumber>
            <Quantity>2</Quantity>
            <Price>2,19</Price>
            <Cost>4,38</Cost>
            <Currency>USD</Currency>
          </Item>
        </Items>
      </Order>
    </ns0:Orders>
    

    您可以从此网址找到架构和地图的完整源代码。http://blog.sarslan.com/group-source-schema-in-a-map/

    【讨论】:

    • 看起来不错,但您在重建解决方案期间忘记了平面文件架构中的the header。我也得到一个错误:The Scripting functoid, that connects to target node 'Order', has an error in its 'Xslt Call-Template' definition: 'There is not an xsl:template node at the root of the xslt.'
    • 你说得对,我完全忘记了标题行,我在 XSLT 脚本上对其进行了更改。我没有得到这个例外。为了比较,您可以从此blog.sarslan.com/wp-content/uploads/2017/09/…下载解决方案文件
    猜你喜欢
    • 1970-01-01
    • 2018-02-28
    • 1970-01-01
    • 1970-01-01
    • 2012-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-19
    相关资源
    最近更新 更多