This is an automated email from the ASF dual-hosted git repository.
jadams pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/daffodil.git
The following commit(s) were added to refs/heads/main by this push:
new 0a47acb82 Evaluate assert/discriminator expressions after groupContent
0a47acb82 is described below
commit 0a47acb82869d17be5abc5d0386aff9c4a45c454
Author: Josh Adams <[email protected]>
AuthorDate: Tue Feb 14 09:59:24 2023 -0500
Evaluate assert/discriminator expressions after groupContent
According to 9.5 of the DFDL spec assert and discriminators with
expressions should be processed after the content of their enclosing
sequence, group, or choice. Before these expressions were always being
processed before the content.
This commit also moves the setVariable expression evaluaiton to the
correct place, which is before the enclosing group.
Added tests for the following:
- Sequence body succeeds but discriminator fails
- Sequence body fails and discriminator fails
- Sequence body fails but discriminator succeeds and references an
element in the partial sequence body infoset
- Sequence body fails and discriminator fails and references an
element in the partial sequence body infoset
DAFFODIL-1971, DAFFODIL-1590
---
.../daffodil/core/dsom/DFDLStatementMixin.scala | 7 +-
.../org/apache/daffodil/core/grammar/Grammar.scala | 22 ++-
.../core/grammar/HasStatementsGrammarMixin.scala | 15 +-
.../core/grammar/ModelGroupGrammarMixin.scala | 6 +-
.../daffodil/core/grammar/TermGrammarMixin.scala | 9 +
.../runtime1/processors/parsers/PState.scala | 18 ++
.../runtime1/processors/parsers/Parser.scala | 34 ++--
.../section07/discriminators/discriminator.tdml | 187 ++++++++++++++++-----
.../discriminators/TestDiscriminators.scala | 6 +-
9 files changed, 236 insertions(+), 68 deletions(-)
diff --git
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/DFDLStatementMixin.scala
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/DFDLStatementMixin.scala
index 035faf010..497a08bc5 100644
---
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/DFDLStatementMixin.scala
+++
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/DFDLStatementMixin.scala
@@ -213,10 +213,11 @@ trait ProvidesDFDLStatementMixin extends ThrowsSDE with
HasTermCheck {
st.testKind != TestKind.Pattern
}
- final lazy val patternStatements: Seq[DFDLStatement] = patternAsserts ++
patternDiscrims
+ // Discriminator statements must be before asserts
+ final lazy val patternStatements: Seq[DFDLStatement] = patternDiscrims ++
patternAsserts
- final lazy val lowPriorityStatements: Seq[DFDLStatement] =
- setVariableStatements ++ nonPatternAsserts ++ nonPatternDiscrims
+ final lazy val assertDiscrimExpressionStatements: Seq[DFDLStatement] =
+ nonPatternDiscrims ++ nonPatternAsserts
final protected lazy val localStatements = this.annotationObjs.collect {
case st: DFDLStatement => st
diff --git
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/Grammar.scala
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/Grammar.scala
index da6613d90..47f1f3740 100644
---
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/Grammar.scala
+++
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/Grammar.scala
@@ -21,6 +21,7 @@ import org.apache.daffodil.core.compiler.ForParser
import org.apache.daffodil.core.compiler.ForUnparser
import org.apache.daffodil.core.dsom.*
import org.apache.daffodil.lib.exceptions.Assert
+import
org.apache.daffodil.runtime1.processors.parsers.AssertExpressionEvaluationParser
import org.apache.daffodil.runtime1.processors.parsers.NadaParser
import org.apache.daffodil.runtime1.processors.parsers.SeqCompParser
import org.apache.daffodil.runtime1.processors.unparsers.SeqCompUnparser
@@ -83,14 +84,27 @@ class SeqComp private (context: SchemaComponent, children:
Seq[Gram])
protected final override def close = ")"
lazy val parserChildren =
- children.filter(_.forWhat != ForUnparser).map { _.parser }.filterNot {
- _.isInstanceOf[NadaParser]
- }
+ children
+ .filter(_.forWhat != ForUnparser)
+ .map { _.parser }
+ .filterNot {
+ _.isInstanceOf[NadaParser]
+ }
+ .toArray
+
+ lazy val assertExpressionChildren = parserChildren.filter {
+ _.isInstanceOf[AssertExpressionEvaluationParser]
+ }.toArray
final override lazy val parser = {
if (parserChildren.isEmpty) new NadaParser(context.runtimeData)
else if (parserChildren.length == 1) parserChildren.head
- else new SeqCompParser(context.runtimeData, parserChildren.toArray)
+ else
+ new SeqCompParser(
+ context.runtimeData,
+ parserChildren,
+ assertExpressionChildren
+ )
}
lazy val unparserChildren = {
diff --git
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/HasStatementsGrammarMixin.scala
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/HasStatementsGrammarMixin.scala
index af8634d87..7862f7e71 100644
---
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/HasStatementsGrammarMixin.scala
+++
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/HasStatementsGrammarMixin.scala
@@ -21,13 +21,16 @@ import org.apache.daffodil.core.dsom.Term
trait HasStatementsGrammarMixin extends GrammarMixin { self: Term =>
- // Includes setVariable as well as assert/discriminator statements that
- // are not testKind="pattern"
- private lazy val lowPriorityStatementGrams = lowPriorityStatements.map {
_.gram(self) }
+ // Includes assert/discriminator statements that are not testKind="pattern"
+ private lazy val assertDiscrimExpressionStatementGrams =
+ assertDiscrimExpressionStatements.map { _.gram(self) }
- final lazy val dfdlLowPriorityStatementEvaluations =
- prod("dfdlStatementEvaluations", lowPriorityStatementGrams.length > 0) {
- lowPriorityStatementGrams.fold(mt) { _ ~ _ }
+ final lazy val dfdlAssertDiscrimExpressionStatementEvaluations =
+ prod(
+ "dfdlAssertDiscrimExpressionStatementEvaluations",
+ assertDiscrimExpressionStatementGrams.length > 0
+ ) {
+ assertDiscrimExpressionStatementGrams.fold(mt) { _ ~ _ }
}
// assert/discriminator statements with testKind="pattern"
diff --git
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/ModelGroupGrammarMixin.scala
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/ModelGroupGrammarMixin.scala
index 7a8735c1f..161a6da31 100644
---
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/ModelGroupGrammarMixin.scala
+++
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/ModelGroupGrammarMixin.scala
@@ -50,8 +50,10 @@ trait ModelGroupGrammarMixin
// See 9.5 Evaluation Order for Statement Annotations
dfdlPatternStatementEvaluations ~ // Assert and Discriminator statements
with testKind="pattern"
dfdlScopeBegin ~ // newVariableInstance
- dfdlLowPriorityStatementEvaluations ~ // setVariable and the rest of the
Assert and Discriminator statements
- groupLeftFraming ~ groupContentWithInitiatorTerminator ~
groupRightFraming ~ dfdlScopeEnd
+ dfdlSetVariableStatements ~
+ groupLeftFraming ~ groupContentWithInitiatorTerminator ~
groupRightFraming ~
+ dfdlAssertDiscrimExpressionStatementEvaluations ~ // The rest of the
Assert and Discriminator statements
+ dfdlScopeEnd
}
private lazy val groupContentWithInitiatorTerminator =
diff --git
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/TermGrammarMixin.scala
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/TermGrammarMixin.scala
index f0d37a8ff..995a97cd8 100644
---
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/TermGrammarMixin.scala
+++
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/TermGrammarMixin.scala
@@ -48,6 +48,15 @@ trait TermGrammarMixin extends AlignedMixin with
BitOrderMixin with TermRuntime1
newVarEnds.fold(mt) { _ ~ _ }
}
+ private lazy val setVars = this.setVariableStatements
+
+ private lazy val setVarGrams = setVars.map { _.gram(self) }
+
+ protected lazy val dfdlSetVariableStatements =
+ prod("dfdlSetVariableStatments", setVarGrams.length > 0) {
+ setVarGrams.fold(mt) { _ ~ _ }
+ }
+
/**
* Mandatory text alignment or mta
*
diff --git
a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/PState.scala
b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/PState.scala
index 8bda3425a..fa64d628b 100644
---
a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/PState.scala
+++
b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/PState.scala
@@ -564,6 +564,24 @@ final class PState private (
}
}
+ /**
+ * This function is used for cases where a parse must be performed after
there
+ * has already been a failed parse of an enclosing element/sequence. Most
+ * common example of this would be a choice branch containing a sequence with
+ * an annotated assert expression. According to 9.5.2 of the DFDL spec this
+ * assert expression needs to be parsed regardless of whether or not the
+ * enclosing sequence content parses or not as the assert expression may be
+ * used as a discriminator for the choice branch.
+ */
+ def withTempSuccess(func: (PState) => Unit): ProcessorResult = {
+ val priorProcessorStatus = processorStatus
+ setSuccess()
+ func(this)
+ val funcStatus = processorStatus
+ _processorStatus = priorProcessorStatus
+ funcStatus
+ }
+
def suspensions = Seq.empty
}
diff --git
a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/Parser.scala
b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/Parser.scala
index c90d57f98..6e978e37a 100644
---
a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/Parser.scala
+++
b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/Parser.scala
@@ -227,26 +227,40 @@ abstract class CombinatorParser(override val context:
RuntimeData)
extends Parser
with CombinatorProcessor
-final class SeqCompParser(context: RuntimeData, val childParsers:
Array[Parser])
- extends CombinatorParser(context) {
+final class SeqCompParser(
+ context: RuntimeData,
+ val childParsers: Array[Parser],
+ testAssert: Array[Parser]
+) extends CombinatorParser(context) {
override def runtimeDependencies = Vector()
override def childProcessors = childParsers.toVector
override def nom = "seq"
- val numChildParsers = childParsers.size
+ val optDiscrimParser = childParsers.collectFirst {
+ case ae: AssertExpressionEvaluationParser if (ae.discrim) => ae
+ }
+ val nonDiscrimChildren = childParsers.diff(optDiscrimParser.toSeq)
def parse(pstate: PState): Unit = {
- var i: Int = 0
- while (i < numChildParsers) {
- val parser = childParsers(i)
- parser.parse1(pstate)
- if (pstate.processorStatus ne Success)
- return
+ var i = 0
+ val numNonDiscrimChildren = nonDiscrimChildren.size
+
+ // Handle all non discriminator child parsers first
+ while ((i < numNonDiscrimChildren) && (pstate.processorStatus eq Success))
{
+ nonDiscrimChildren(i).parse1(pstate)
i += 1
}
- }
+ // If a discriminator statement exists always parse it, even if there was
a prior failure.
+ // See section 9.5.2 of the DFDL specification.
+ if (optDiscrimParser.isDefined) {
+ if (pstate.processorStatus eq Success)
+ optDiscrimParser.get.parse1(pstate)
+ else
+ pstate.withTempSuccess(optDiscrimParser.get.parse1)
+ }
+ }
}
class ChoiceParser(ctxt: RuntimeData, val childParsers: Array[Parser])
diff --git
a/daffodil-test/src/test/resources/org/apache/daffodil/section07/discriminators/discriminator.tdml
b/daffodil-test/src/test/resources/org/apache/daffodil/section07/discriminators/discriminator.tdml
index 347c56039..7be1a5d26 100644
---
a/daffodil-test/src/test/resources/org/apache/daffodil/section07/discriminators/discriminator.tdml
+++
b/daffodil-test/src/test/resources/org/apache/daffodil/section07/discriminators/discriminator.tdml
@@ -16,16 +16,16 @@
limitations under the License.
-->
-<tdml:testSuite
- suiteName="Discriminator"
+<tdml:testSuite
+ suiteName="Discriminator"
description="Section 7 - Discriminator"
xmlns:ex="http://example.com" xmlns="http://example.com"
- xmlns:tdml="http://www.ibm.com/xmlns/dfdl/testData"
+ xmlns:tdml="http://www.ibm.com/xmlns/dfdl/testData"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/"
+ xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
- defaultRoundTrip="true"
+ defaultRoundTrip="true"
defaultValidation="on">
<tdml:defineSchema name="discrimAssertPlacement">
@@ -209,7 +209,7 @@
<xs:element name="e2" type="xs:int" dfdl:lengthKind="delimited" />
</xs:sequence>
</xs:group>
-
+
<xs:group name="namedGroup2">
<xs:sequence>
<xs:element name="e3" type="xs:string"
@@ -231,7 +231,7 @@
</xs:group>
</xs:complexType>
</xs:element>
-
+
<xs:element name="Item2" dfdl:lengthKind="implicit">
<xs:complexType>
<xs:choice>
@@ -292,7 +292,7 @@
<!--
Test name: discrimOnSimpleType
Schema: s0, root e0
- Purpose: This test demonstrates the use of a discriminator on a simple
+ Purpose: This test demonstrates the use of a discriminator on a simple
type. The document meets the discriminator and should pass.
-->
@@ -309,7 +309,7 @@
<!--
Test name: discrimOnGroupRef
Schema: s0, root Item
- Purpose: This test demonstrates the use of a discriminator on a group
+ Purpose: This test demonstrates the use of a discriminator on a group
reference. The document meets the discriminator and should pass.
-->
@@ -326,11 +326,11 @@
</tdml:dfdlInfoset>
</tdml:infoset>
</tdml:parserTestCase>
-
+
<!--
Test name: discrimOnGroupRef2
Schema: s0, root Item
- Purpose: This test demonstrates the use of a discriminator on a group
+ Purpose: This test demonstrates the use of a discriminator on a group
reference. The document meets the discriminator and should pass.
-->
@@ -351,7 +351,7 @@
<!--
Test name: discrimOnElementRef
Schema: s0, root Item_01
- Purpose: This test demonstrates the use of a discriminator on an element
+ Purpose: This test demonstrates the use of a discriminator on an element
reference. The document meets the discriminator and should pass.
-->
@@ -402,7 +402,7 @@
<!--
Test name: discriminatorGuidesChoice2
Schema: choice1, root c1
- Purpose: The element should fail, and the discriminator should still
+ Purpose: The element should fail, and the discriminator should still
be checked. The error message should express
the discriminator failure.
-->
@@ -684,7 +684,7 @@
<tdml:error>Schema Definition Error</tdml:error>
</tdml:errors>
</tdml:parserTestCase>
-
+
<tdml:defineSchema name="discrimExpression">
<xs:include
schemaLocation="/org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
<dfdl:format ref="ex:GeneralFormat" />
@@ -714,8 +714,8 @@
<xs:sequence>
<xs:annotation>
<xs:appinfo source="http://www.ogf.org/dfdl/">
- <!-- NOTE That this discriminator executes regardless of
whether the
- sequence content (int element) below parses successfully.
So if that int parse fails,
+ <!-- NOTE That this discriminator executes regardless of
whether the
+ sequence content (int element) below parses successfully.
So if that int parse fails,
the discriminator still will be true, and we will NOT
backtrack to have zero occurrences
of the ints array. -->
<dfdl:discriminator testKind="expression" test='{
fn:true() }' />
@@ -730,30 +730,79 @@
</xs:complexType>
</xs:element>
+ <xs:element name="e4">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="ints" dfdl:occursCountKind="implicit"
minOccurs="0" maxOccurs="5">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:annotation>
+ <xs:appinfo source="http://www.ogf.org/dfdl/">
+ <!-- NOTE That this discriminator executes regardless of
whether the
+ sequence content (int element) below parses successfully.
So with the discriminator
+ set to false we will fail to parse any int's and instead
parse everything as a
+ string -->
+ <dfdl:discriminator testKind="expression" test='{
fn:false() }' />
+ </xs:appinfo>
+ </xs:annotation>
+ <xs:element name="int" type="xs:int"
dfdl:lengthKind="explicit" dfdl:length="1" dfdl:lengthUnits="bytes" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="string" type="xs:string"
dfdl:lengthKind="explicit" dfdl:length="3" dfdl:lengthUnits="bytes" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="e5">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="ints" dfdl:occursCountKind="implicit"
minOccurs="0" maxOccurs="5">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:annotation>
+ <xs:appinfo source="http://www.ogf.org/dfdl/">
+ <!-- NOTE That this discriminator executes regardless of
whether
+ the sequence content (int element) below parses
successfully. In
+ this test the discriminator references a successfully
parsing
+ element in the partial infoset of an otherwise failing
sequence body. -->
+ <dfdl:discriminator testKind="expression" test='{ ex:int1
eq 1 }' />
+ </xs:appinfo>
+ </xs:annotation>
+ <xs:element name="int1" type="xs:int"
dfdl:lengthKind="explicit" dfdl:length="1" dfdl:lengthUnits="bytes" />
+ <xs:element name="int2" type="xs:int"
dfdl:lengthKind="explicit" dfdl:length="1" dfdl:lengthUnits="bytes" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="string" type="xs:string"
dfdl:lengthKind="explicit" dfdl:length="3" dfdl:lengthUnits="bytes" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
</tdml:defineSchema>
-
+
<tdml:parserTestCase name="discrimExpression_01"
root="e1" model="discrimExpression"
description="Property Name: test - DFDL-7-076R">
<tdml:document><![CDATA[123]]></tdml:document>
<tdml:infoset>
<tdml:dfdlInfoset>
- <e1>123</e1>
+ <e1>123</e1>
</tdml:dfdlInfoset>
</tdml:infoset>
</tdml:parserTestCase>
-
+
<tdml:parserTestCase name="discrimExpression_02"
root="e2" model="discrimExpression"
description="Property Name: test - DFDL-7-076R">
<tdml:document>cats</tdml:document>
<tdml:infoset>
<tdml:dfdlInfoset>
- <e2>cats</e2>
+ <e2>cats</e2>
</tdml:dfdlInfoset>
</tdml:infoset>
</tdml:parserTestCase>
-
+
<tdml:parserTestCase name="discrimExpression_03"
root="e2" model="discrimExpression"
description="Property Name: test - DFDL-7-076R">
@@ -765,13 +814,67 @@
<tdml:parserTestCase name="discrimExpression_04"
root="e3" model="discrimExpression"
- description="Property Name: test - DFDL-7-076R">
+ description="Verify that a discriminator will prevent backtracking
+ regardless of whether the sequence content parses succesfully">
<tdml:document><![CDATA[abc]]></tdml:document>
+ <tdml:errors>
+ <tdml:error>Parse Error</tdml:error>
+ <tdml:error>Failed to populate ex:ints</tdml:error>
+ <tdml:error>Unable to parse xs:int from text: a</tdml:error>
+ </tdml:errors>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase name="discrimExpression_05"
+ root="e4" model="discrimExpression"
+ description="Verify that a failed discriminator will be handled correctly
+ when the body of the sequence parses successfully">
+ <tdml:document><![CDATA[123]]></tdml:document>
<tdml:infoset>
<tdml:dfdlInfoset>
- <e3>
+ <e4>
+ <string>123</string>
+ </e4>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase name="discrimExpression_06"
+ root="e4" model="discrimExpression"
+ description="Verify correct behavior when the body of a sequence fails and
+ the discriminator fails">
+ <tdml:document><![CDATA[abc]]></tdml:document>
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <e4>
<string>abc</string>
- </e3>
+ </e4>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase name="discrimExpression_07"
+ root="e5" model="discrimExpression"
+ description="Sequence body fails, but discriminator succeeds and references
+ elements in partial body infoset">
+ <tdml:document><![CDATA[1ab]]></tdml:document>
+ <tdml:errors>
+ <tdml:error>Parse Error</tdml:error>
+ <tdml:error>Failed to populate ex:ints</tdml:error>
+ <tdml:error>Unable to parse xs:int from text: a</tdml:error>
+ <tdml:error>Schema context: ex:int2</tdml:error>
+ </tdml:errors>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase name="discrimExpression_08"
+ root="e5" model="discrimExpression"
+ description="Sequence body fails and so does the discriminator that
+ references partial sequence body infoset">
+ <tdml:document><![CDATA[2ab]]></tdml:document>
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <e5>
+ <string>2ab</string>
+ </e5>
</tdml:dfdlInfoset>
</tdml:infoset>
</tdml:parserTestCase>
@@ -964,7 +1067,7 @@
</xs:sequence>
</xs:complexType>
</xs:element>
-
+
<xs:element name="r2">
<xs:complexType>
<xs:sequence>
@@ -981,7 +1084,7 @@
</xs:element>
</tdml:defineSchema>
-
+
<!--
Test name: discrimPatternMatch
Schema: discrimWithVariable
@@ -1001,7 +1104,7 @@
</tdml:dfdlInfoset>
</tdml:infoset>
</tdml:parserTestCase>
-
+
<!--
Test name: discrimPatternNoMatch
Schema: discrimWithVariable
@@ -1036,8 +1139,8 @@
</xs:appinfo>
</xs:annotation>
</xs:sequence>
- <xs:element name="opt1" minOccurs="0" maxOccurs="1"
- dfdl:occursCountKind="implicit" type="xs:string"
+ <xs:element name="opt1" minOccurs="0" maxOccurs="1"
+ dfdl:occursCountKind="implicit" type="xs:string"
dfdl:lengthKind="delimited"
dfdl:terminator=";" />
</xs:sequence>
@@ -1047,14 +1150,14 @@
<xs:element name="r0">
<xs:complexType>
<xs:sequence>
- <xs:element name="flag" type="xs:int" dfdl:length="1"
- dfdl:lengthKind="explicit" minOccurs="0"
+ <xs:element name="flag" type="xs:int" dfdl:length="1"
+ dfdl:lengthKind="explicit" minOccurs="0"
dfdl:occursCountKind="implicit" />
<xs:choice>
<xs:element name="hasFlag1" type="xs:string"
dfdl:lengthKind="delimited">
<xs:annotation>
<xs:appinfo source="http://www.ogf.org/dfdl/">
- <dfdl:discriminator>{
+ <dfdl:discriminator>{
../flag eq 1 }
</dfdl:discriminator>
</xs:appinfo>
@@ -1069,13 +1172,13 @@
<xs:element name="r1">
<xs:complexType>
<xs:sequence>
- <xs:element name="flag" type="xs:int" dfdl:length="1"
+ <xs:element name="flag" type="xs:int" dfdl:length="1"
dfdl:lengthKind="explicit" minOccurs="0"
dfdl:occursCountKind="implicit" />
<xs:choice>
<xs:element name="hasFlag1" type="xs:string"
dfdl:lengthKind="delimited">
<xs:annotation>
<xs:appinfo source="http://www.ogf.org/dfdl/">
- <dfdl:assert>{
+ <dfdl:assert>{
../flag eq 1 }
</dfdl:assert>
</xs:appinfo>
@@ -1090,11 +1193,11 @@
<xs:element name="r2">
<xs:complexType>
<xs:sequence>
- <xs:element name="count" type="xs:int" dfdl:length="1"
+ <xs:element name="count" type="xs:int" dfdl:length="1"
dfdl:lengthKind="explicit" minOccurs="0"
dfdl:occursCountKind="implicit" />
- <xs:element name="v" type="xs:string"
- dfdl:occursCountKind="expression"
- dfdl:occursCount="{ ../count }"
+ <xs:element name="v" type="xs:string"
+ dfdl:occursCountKind="expression"
+ dfdl:occursCount="{ ../count }"
dfdl:lengthKind="delimited"
maxOccurs="unbounded" />
</xs:sequence>
@@ -1104,13 +1207,13 @@
<xs:element name="r3">
<xs:complexType>
<xs:sequence>
- <xs:element name="flag" type="xs:int" dfdl:length="1"
+ <xs:element name="flag" type="xs:int" dfdl:length="1"
dfdl:lengthKind="explicit" minOccurs="0"
dfdl:occursCountKind="implicit" />
<xs:choice>
<xs:element name="hasFlag1" type="xs:string"
dfdl:lengthKind="delimited">
<xs:annotation>
<xs:appinfo source="http://www.ogf.org/dfdl/">
- <dfdl:discriminator>{
+ <dfdl:discriminator>{
dfdl:valueLength(../flag, 'bytes') ge 1 }
</dfdl:discriminator>
</xs:appinfo>
@@ -1125,13 +1228,13 @@
<xs:element name="r4">
<xs:complexType>
<xs:sequence>
- <xs:element name="flag" type="xs:int" dfdl:length="1"
+ <xs:element name="flag" type="xs:int" dfdl:length="1"
dfdl:lengthKind="explicit" minOccurs="0"
dfdl:occursCountKind="implicit" />
<xs:choice>
<xs:element name="hasFlag1" type="xs:string"
dfdl:lengthKind="delimited">
<xs:annotation>
<xs:appinfo source="http://www.ogf.org/dfdl/">
- <dfdl:discriminator>{
+ <dfdl:discriminator>{
dfdl:valueLength(.., 'bytes') ge 1 }
</dfdl:discriminator>
</xs:appinfo>
diff --git
a/daffodil-test/src/test/scala/org/apache/daffodil/section07/discriminators/TestDiscriminators.scala
b/daffodil-test/src/test/scala/org/apache/daffodil/section07/discriminators/TestDiscriminators.scala
index 6937912c8..f560495d2 100644
---
a/daffodil-test/src/test/scala/org/apache/daffodil/section07/discriminators/TestDiscriminators.scala
+++
b/daffodil-test/src/test/scala/org/apache/daffodil/section07/discriminators/TestDiscriminators.scala
@@ -67,7 +67,11 @@ class TestDiscriminator extends TdmlTests {
@Test def discrimExpression_03 = test
// DAFFODIL-1971
- @Ignore @Test def discrimExpression_04 = test
+ @Test def discrimExpression_04 = test
+ @Test def discrimExpression_05 = test
+ @Test def discrimExpression_06 = test
+ @Test def discrimExpression_07 = test
+ @Test def discrimExpression_08 = test
@Test def discrimFailStopsFollowingAssert1 = test
@Test def discrimPEnotSDE1 = test