在 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 测试的
我正在尝试使用 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 测试的