...
- the child node itself, or
- the first child Attribute or Record Node of the child node.
See 3.4.2 Attribute Node for details of discriminators. A Choice Node has no attributes other than the common attributes (see 3.1).
<Choice>
<Sequence name="option1">
<Attr name="type1" discriminator="1" type="String"/>
<Attr name="numberValue" bytes="2" type="Integer"/>
</Sequence>
<Sequence name="option2">
<Attr name="type" discriminator="2" type="String"/>
<Attr name="stringValue" bytes="8" type="String"/>
</Sequence>
</Choice>
<Attr name="final" bytes="2" type="Integer"/>
In the snippet above, if the first byte encountered is 1 then the next section of the file will be recognised as a Sequence Node option1, the next 2 bytes will be interpreted as a number, before moving on to the Attribute Node final.
If the first byte encountered is 2 then the next section of the file will be recognised as a Sequence Node option2, the next 8 bytes will be interpreted as a string, before moving on to the Attribute Node final.
If the first byte encountered is a 3 then the reader will fail with an error since the snippet only handles 1 or 2 in the first byte. If a 3 is a valid possibility there are three possible solutions:
Solution 1
Add an additional Attribute Node to the Choice Node with a discriminator of 3, as below:
Code Block | ||
---|---|---|
| ||
<Choice> |
...
<Sequence name="option1"> |
...
<Attr name="type1" discriminator="1" type="String"/> |
...
<Attr name="numberValue" bytes="2" type="Integer"/> |
...
</Sequence> |
...
<Sequence name="option2"> |
...
<Attr name="type2" discriminator="2" type="String"/> |
...
<Attr name="stringValue" bytes="8" type="String"/> |
...
</Sequence> |
...
<Attr name="type3" discriminator="3" type="String/> |
...
</Choice> |
...
<Attr name="final" bytes="2" type="Integer"/> |
Solution 2
Add an Attribute Node to the Choice Node to pick up any value that is not 1 or 2, as below:
Code Block | ||
---|---|---|
| ||
<Choice> |
...
<Sequence name="option1"> |
...
<Attr name="type1" discriminator="1" type="String"/> |
...
<Attr name="numberValue" bytes="2" type="Integer"/> |
...
</Sequence> |
...
<Sequence name="option2"> |
...
<Attr name="type2" discriminator="2" type="String"/> |
...
<Attr name="stringValue" bytes="8" type="String"/> |
...
</Sequence> |
...
<Attr name="type3" bytes="1" type="String/> |
...
</Choice> |
...
<Attr name="final" bytes="2" type="Integer"/> |
Solution 3
Note that in the snippet above, if no discriminator is set on the Attribute Node type3 then the number of bytes or bits must be set. You cannot have more than one generic option like this in a Choice Node, since this will make the grammar ambiguous.
Solution 3
Make the whole choice node optional, as below:
Code Block | ||
---|---|---|
| ||
<Choice optional="T"> |
...
<Sequence name="option1"> |
...
<Attr name="type1" discriminator="1" type="String"/> |
...
<Attr name="numberValue" bytes="2" type="Integer"/> |
...
</Sequence> |
...
<Sequence name="option2"> |
...
<Attr name="type2" discriminator="2" type="String"/> |
...
<Attr name="stringValue" bytes="8" type="String"/> |
...
</Sequence> |
...
</Choice> |
...
<Attr name="final" bytes="2" type="Integer"/> |
In the snippet above, if the first byte is not 1 or 2, the Choice Node will be skipped and the first byte will be recognised as the Attribute Node final.