在 DFDL 中跳出循环
Breaking out of loop in DFDL
我正在尝试使用 DFDL 将 FLAT 文件转换为 XML。它具有以下格式:
每个元素 5 byte.All 都在同一行,但我将它们分开以避免混淆。我将在其中按第一个字母来处理元素。
0AAAA
81AAA
eeeee
qqqqq
82BBB
rrrrr
sssss
9QQQQ
现在 0 和 9 是伟大的parent我们不必担心它们。 8是parent,81AAA的第二个字节(即1)决定了它的children的格式。可以有很多 8 和很多 children of a 8 parent(但它们都将具有相同的格式)。
我尝试了一种模式,但一旦它进入 children(eeeee),它就不会退出,并且每条记录仅以 children 格式打印。
以下是我认为描述您的数据的架构,已在 Daffodil 2.2.0 上测试:
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
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" />
</xs:appinfo>
</xs:annotation>
<xs:element name="Root">
<xs:complexType>
<xs:sequence>
<xs:element name="GrandParent" maxOccurs="unbounded">
<xs:complexType>
<xs:choice dfdl:initiatedContent="yes">
<xs:element name="Zero" dfdl:initiator="0">
<xs:complexType>
<xs:sequence>
<xs:element name="Value" type="xs:string" dfdl:length="4" dfdl:lengthKind="explicit" />
<xs:element ref="Eight" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Nine" dfdl:initiator="9">
<xs:complexType>
<xs:sequence>
<xs:element name="Value" type="xs:string" dfdl:length="4" dfdl:lengthKind="explicit" />
<xs:element ref="Eight" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Eight" dfdl:initiator="8">
<xs:complexType>
<xs:sequence>
<xs:element name="ChildrenFormat" type="xs:string" dfdl:length="1" dfdl:lengthKind="explicit" />
<xs:element name="Value" type="xs:string" dfdl:length="3" dfdl:lengthKind="explicit" />
<xs:choice dfdl:choiceDispatchKey="{ ./ChildrenFormat }">
<xs:element ref="One" maxOccurs="unbounded" dfdl:choiceBranchKey="1" />
<xs:element ref="Two" maxOccurs="unbounded" dfdl:choiceBranchKey="2" />
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="One" type="xs:string" dfdl:length="5" dfdl:lengthKind="explicit">
<xs:annotation>
<xs:appinfo source="http://www.ogf.org/dfdl/">
<dfdl:discriminator test="{ fn:not(fn:starts-with(., '8') or fn:starts-with(., '9')) }" />
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="Two" type="xs:string" dfdl:length="5" dfdl:lengthKind="explicit">
<xs:annotation>
<xs:appinfo source="http://www.ogf.org/dfdl/">
<dfdl:discriminator test="{ fn:not(fn:starts-with(., '8') or fn:starts-with(., '9')) }" />
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:schema>
工作原理说明:
- 数据的根是无限数量的 GrandParent 元素
- 每个 GrandParent 元素包含一个零或一个九,具体取决于发起者。发起者消耗祖父母数据的5个字节中的第一个
- Zero/Nine 元素包含一个 Value,它消耗了 gradparent 数据的剩余 4 个字节
- Value后面是零个或多个八个元素
- 每个八元素都有一个起始符“8”,占用 5 个字节中的第一个字节
- 每个八元素都有一个 ChildrenFormat,占用 5 个字节中的第二个
- 每个八元素都有一个值,占用 5 个字节中的最后 3 个
- 每个八元素都有无限数量的全一或全二元素
- 一个choiceDispatchKey/Branch用于判断是解析all One还是all Two元素,调度掉ChildrenFormat元素
- 每个一或二元素占用 5 个字节
- 为了确定一个或两个元素的无限数量何时结束,在 One/Two 元素上放置了一个鉴别器。当解析为 One/Two 的数据不是以“8”或“9”开头时,此鉴别器会失败。
- 此外,为简单起见,所有字段都被视为字符串
这样,您的示例数据将解析为如下信息集:
<Root>
<GrandParent>
<Zero>
<Value>AAAA</Value>
<Eight>
<ChildrenFormat>1</ChildrenFormat>
<Value>AAA</Value>
<One>eeeee</One>
<One>qqqqq</One>
</Eight>
<Eight>
<ChildrenFormat>2</ChildrenFormat>
<Value>BBB</Value>
<Two>rrrrr</Two>
<Two>sssss</Two>
</Eight>
</Zero>
</GrandParent>
<GrandParent>
<Nine>
<Value>QQQQ</Value>
</Nine>
</GrandParent>
</Root>
我正在尝试使用 DFDL 将 FLAT 文件转换为 XML。它具有以下格式: 每个元素 5 byte.All 都在同一行,但我将它们分开以避免混淆。我将在其中按第一个字母来处理元素。
0AAAA
81AAA
eeeee
qqqqq
82BBB
rrrrr
sssss
9QQQQ
现在 0 和 9 是伟大的parent我们不必担心它们。 8是parent,81AAA的第二个字节(即1)决定了它的children的格式。可以有很多 8 和很多 children of a 8 parent(但它们都将具有相同的格式)。
我尝试了一种模式,但一旦它进入 children(eeeee),它就不会退出,并且每条记录仅以 children 格式打印。
以下是我认为描述您的数据的架构,已在 Daffodil 2.2.0 上测试:
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
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" />
</xs:appinfo>
</xs:annotation>
<xs:element name="Root">
<xs:complexType>
<xs:sequence>
<xs:element name="GrandParent" maxOccurs="unbounded">
<xs:complexType>
<xs:choice dfdl:initiatedContent="yes">
<xs:element name="Zero" dfdl:initiator="0">
<xs:complexType>
<xs:sequence>
<xs:element name="Value" type="xs:string" dfdl:length="4" dfdl:lengthKind="explicit" />
<xs:element ref="Eight" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Nine" dfdl:initiator="9">
<xs:complexType>
<xs:sequence>
<xs:element name="Value" type="xs:string" dfdl:length="4" dfdl:lengthKind="explicit" />
<xs:element ref="Eight" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Eight" dfdl:initiator="8">
<xs:complexType>
<xs:sequence>
<xs:element name="ChildrenFormat" type="xs:string" dfdl:length="1" dfdl:lengthKind="explicit" />
<xs:element name="Value" type="xs:string" dfdl:length="3" dfdl:lengthKind="explicit" />
<xs:choice dfdl:choiceDispatchKey="{ ./ChildrenFormat }">
<xs:element ref="One" maxOccurs="unbounded" dfdl:choiceBranchKey="1" />
<xs:element ref="Two" maxOccurs="unbounded" dfdl:choiceBranchKey="2" />
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="One" type="xs:string" dfdl:length="5" dfdl:lengthKind="explicit">
<xs:annotation>
<xs:appinfo source="http://www.ogf.org/dfdl/">
<dfdl:discriminator test="{ fn:not(fn:starts-with(., '8') or fn:starts-with(., '9')) }" />
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="Two" type="xs:string" dfdl:length="5" dfdl:lengthKind="explicit">
<xs:annotation>
<xs:appinfo source="http://www.ogf.org/dfdl/">
<dfdl:discriminator test="{ fn:not(fn:starts-with(., '8') or fn:starts-with(., '9')) }" />
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:schema>
工作原理说明:
- 数据的根是无限数量的 GrandParent 元素
- 每个 GrandParent 元素包含一个零或一个九,具体取决于发起者。发起者消耗祖父母数据的5个字节中的第一个
- Zero/Nine 元素包含一个 Value,它消耗了 gradparent 数据的剩余 4 个字节
- Value后面是零个或多个八个元素
- 每个八元素都有一个起始符“8”,占用 5 个字节中的第一个字节
- 每个八元素都有一个 ChildrenFormat,占用 5 个字节中的第二个
- 每个八元素都有一个值,占用 5 个字节中的最后 3 个
- 每个八元素都有无限数量的全一或全二元素
- 一个choiceDispatchKey/Branch用于判断是解析all One还是all Two元素,调度掉ChildrenFormat元素
- 每个一或二元素占用 5 个字节
- 为了确定一个或两个元素的无限数量何时结束,在 One/Two 元素上放置了一个鉴别器。当解析为 One/Two 的数据不是以“8”或“9”开头时,此鉴别器会失败。
- 此外,为简单起见,所有字段都被视为字符串
这样,您的示例数据将解析为如下信息集:
<Root>
<GrandParent>
<Zero>
<Value>AAAA</Value>
<Eight>
<ChildrenFormat>1</ChildrenFormat>
<Value>AAA</Value>
<One>eeeee</One>
<One>qqqqq</One>
</Eight>
<Eight>
<ChildrenFormat>2</ChildrenFormat>
<Value>BBB</Value>
<Two>rrrrr</Two>
<Two>sssss</Two>
</Eight>
</Zero>
</GrandParent>
<GrandParent>
<Nine>
<Value>QQQQ</Value>
</Nine>
</GrandParent>
</Root>