在 DFDL 中循环

Looping in DFDL

我正在尝试使用 DFDL 和 Daffodil 将 rally complex 固定长度文件转换为 XML。每行将负责一个元素,每行的第一个元素将告诉我它将是哪种元素。它可以是 Parent A 或 Parent B,也可以是 child AA 或 AB 或 BB 或 BA。

其中 Parent A 是一个元素,Parent B 是另一个元素,Child AA 是元素 A 的第一个 child。

一个文件里面有多个Parent A和Parent B。 我尝试了 initiator 标签甚至尝试了 choice 标签,但似乎没有任何效果。谁能帮帮我。

没有示例数据很难给出完整的答案,但使用启动器和选择可能是正确的方法。根据特定数据,可能有更简单的模式,但通用解决方案可能如下所示:

<xs:schema
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/">

  <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd" />

  <xs:annotation>
    <xs:appinfo source="http://www.ogf.org/dfdl/">
      <dfdl:format ref="GeneralFormat" lengthKind="delimited" />
    </xs:appinfo>
  </xs:annotation>

  <xs:element name="File">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Record" maxOccurs="unbounded">
          <xs:complexType>
            <xs:choice dfdl:initiatedContent="yes">
              <xs:element name="ParentA" dfdl:initiator="ParentA:">
                <xs:complexType>
                  <xs:sequence dfdl:separator="%NL;" dfdl:separatorPosition="postfix">
                    <xs:element name="Content" type="xs:string"/>
                    <xs:element name="Record" maxOccurs="unbounded">
                      <xs:complexType>
                        <xs:choice dfdl:initiatedContent="yes">
                          <xs:element name="ChildAA"  type="xs:string" dfdl:initiator="ChildAA:" />
                          <xs:element name="ChildAB"  type="xs:string" dfdl:initiator="ChildAB:" />
                        </xs:choice>
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
              <xs:element name="ParentB" dfdl:initiator="ParentB:">
                <xs:complexType>
                  <xs:sequence dfdl:separator="%NL;" dfdl:separatorPosition="postfix">
                    <xs:element name="Content" type="xs:string" />
                    <xs:element name="Record" maxOccurs="unbounded">
                      <xs:complexType>
                        <xs:choice dfdl:initiatedContent="yes">
                          <xs:element name="ChildBA" type="xs:string" dfdl:initiator="ChildBA:" />
                          <xs:element name="ChildBB" type="xs:string" dfdl:initiator="ChildBB:" />
                        </xs:choice>
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:choice>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

</xs:schema>

此架构具有以下特点:

  • 每个文件都有无限数量的记录。
  • 每个记录都是 ParentA 或 ParentB 元素的选择,由 dfdl:initiator 属性.
  • 决定
  • 每个父元素都包含该父元素的内容(即父发起者之后的内容),后跟无限数量的子记录。
  • 每个子记录也由 dfdl:initator 属性.
  • 决定
  • 后缀换行符用于确定父内容和子内容何时 内容结束.
  • 这不允许 ChildB 元素出现在 ParentA 元素之后,反之亦然——子元素必须始终出现在关联的父元素之后。 (如果这个限制不重要,这个模式可以大大简化)。

以上允许这样的数据:

ParentA:Parent A Content
ChildAA:Child AA Content
ChildAB:Child AB Content
ParentB:Parent B Content
ChildBB:Child BB Content
ParentA:Parent A Content
ChildAB:Child AB Content

这会像这样解析成 XML 信息集:

<File>
  <Record>
    <ParentA>
      <Content>Parent A Content</Content>
      <Record>
        <ChildAA>Child AA Content</ChildAA>
      </Record>
      <Record>
        <ChildAB>Child AB Content</ChildAB>
      </Record>
    </ParentA>
  </Record>
  <Record>
    <ParentB>
      <Content>Parent B Content</Content>
      <Record>
        <ChildBB>Child BB Content</ChildBB>
      </Record>
    </ParentB>
  </Record>
  <Record>
    <ParentA>
      <Content>Parent A Content</Content>
      <Record>
        <ChildAB>Child AB Content</ChildAB>
      </Record>
    </ParentA>
  </Record>
</File>

以上是用 Apache Daffodil 2.2.0 测试的