Ниже приведена схема, которая, как мне кажется, описывает ваши данные, протестированные на 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>
Описание того, как это работает:
- Кореньdata - это неограниченное количество элементов GrandParent
- Каждый элемент GrandParent содержит либо ноль, либо девятку, в зависимости от инициатора.Инициатор потребляет первый из 5 байтов данных прародителя
- Элементы Zero / Nine содержат значение, которое потребляет оставшиеся 4 байта данных родительского элемента
- После значения ноль или болееВосемь элементов
- Каждый элемент Eight имеет инициатор "8", который потребляет первый из 5 байтов
- Каждый элемент Eight имеет формат ChildrenFormat, который потребляет второй из 5 байтов
- Каждый восьмой элемент имеет значение, которое занимает последние 3 из 5 байтов
- Каждый восьмой элемент имеет неограниченное число либо всех одного, либо всех двух элементов
- choiceDispatchKey / Branch используется для определения того,чтобы проанализировать все один или все два элемента, отправка из элемента ChildrenFormat
- каждого одного или двух элементов занимает 5 байтов
- , чтобы определить, когда заканчивается неограниченное число элементов одного или двух,дискриминатор размещается на элементах 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>