diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/core/runtime1/TermRuntime1Mixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/core/runtime1/TermRuntime1Mixin.scala index 418a50ceed..2d25012c74 100644 --- a/daffodil-core/src/main/scala/org/apache/daffodil/core/runtime1/TermRuntime1Mixin.scala +++ b/daffodil-core/src/main/scala/org/apache/daffodil/core/runtime1/TermRuntime1Mixin.scala @@ -255,15 +255,18 @@ trait TermRuntime1Mixin { self: Term => val groupedByName = possibles.pnes.groupBy(_.e.namedQName.local) groupedByName.foreach { case (_, sameNamesEB) => if (sameNamesEB.length > 1) { - SDW( - WarnID.NamespaceDifferencesOnly, - "Neighboring QNames differ only by namespaces. " + - "Infoset representations that do not support namespaces " + - "cannot differentiate between these elements and " + - "may fail to unparse. QNames are: %s", - sameNamesEB.map(_.e.namedQName.toExtendedSyntax).mkString(", ") - ) - hasNamesDifferingOnlyByNS = true + val groupedByNamespace = sameNamesEB.groupBy(_.e.namedQName.namespace) + if (groupedByNamespace.size > 1) { + SDW( + WarnID.NamespaceDifferencesOnly, + "Neighboring QNames differ only by namespaces. " + + "Infoset representations that do not support namespaces " + + "cannot differentiate between these elements and " + + "may fail to unparse. QNames are: %s", + sameNamesEB.map(_.e.namedQName.toExtendedSyntax).mkString(", ") + ) + hasNamesDifferingOnlyByNS = true + } } } } @@ -458,12 +461,15 @@ trait TermRuntime1Mixin { self: Term => // the way one would normally expect a collection to be. // So Map[NamedQName, ElementRuntimeData] is not a subtype of Map[QNameBase, ElementRuntimeData] // So we need a cast upward to Map[QNameBase,ElementRuntimeData] - // + // We need the fold because .toMAp overwrites earlier element with duplicate later elements, + // but we don't want that, so instead we deduplicate here with earlier elements taking precedence val eltMap = sibs .map { sib => (sib.e.namedQName, sib.e.erd) } - .toMap + .foldLeft(Map.empty[QNameBase, ElementRuntimeData]) { case (map, (key, value)) => + if (map.contains(key)) map else map + (key -> value) + } .asInstanceOf[Map[QNameBase, ElementRuntimeData]] val resolver = eltMap.size match { case 0 => new NoNextElement(trd, isRequiredStreamingUnparserEvent) diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/infoset/PartialNextElementResolver.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/infoset/PartialNextElementResolver.scala index 4fbff2460c..9ff51df2af 100644 --- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/infoset/PartialNextElementResolver.scala +++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/infoset/PartialNextElementResolver.scala @@ -304,9 +304,9 @@ class SeveralPossibilitiesForNextElement( hasNamespace: Boolean ): Maybe[ElementRuntimeData] = { Logger.log.debug(s""" - NextERDResovler -> trd: $trd\n - NextERDResovler -> looking for: $local\n - NextERDResovler -> nextERDMap: $nextERDMap\n""") + NextERDResolver -> trd: $trd\n + NextERDResolver -> looking for: $local\n + NextERDResolver -> nextERDMap: $nextERDMap\n""") val optnextERD = if (hasNamespace) { val sqn = StepQName( diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/SequenceGroup.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/SequenceGroup.tdml index b4b8d7552c..d0f91b3db5 100644 --- a/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/SequenceGroup.tdml +++ b/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/SequenceGroup.tdml @@ -60,7 +60,7 @@ Schema: emptySDEschema Purpose: This test demonstrates that DFDL allows complexTypes with empty content (not to be confused with NO content) --> - + @@ -1206,12 +1206,58 @@ dfdl:lengthKind="delimited" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + roundTrip="twoPass" + ignoreUnexpectedWarnings="false"> @@ -1286,12 +1332,81 @@ + + + + + + + + + + A + B + C + 1 + x + + + + + + + + + + + + + + + + A + B + C + x + 1 + + + + + + + + + + + + + + + + A + B + C + x + 1 + + + + + + - + @@ -1302,7 +1417,7 @@ Schema: emptySDEschema Purpose: This test demonstrates that DFDL allows complexTypes with empty content (not to be confused with NO content) --> - + diff --git a/daffodil-test/src/test/scala/org/apache/daffodil/section14/sequence_groups/TestSequenceGroups.scala b/daffodil-test/src/test/scala/org/apache/daffodil/section14/sequence_groups/TestSequenceGroups.scala index 819d0fc2ee..873eb6e7b9 100644 --- a/daffodil-test/src/test/scala/org/apache/daffodil/section14/sequence_groups/TestSequenceGroups.scala +++ b/daffodil-test/src/test/scala/org/apache/daffodil/section14/sequence_groups/TestSequenceGroups.scala @@ -106,6 +106,9 @@ class TestSequenceGroups { @Test def test_hiddenGroupNested2(): Unit = { runner_02.runOneTest("hiddenGroupNested2") } @Test def test_nestedGroupRefs(): Unit = { runner_02.runOneTest("nestedGroupRefs") } @Test def test_nestedGroupRefs2(): Unit = { runner_02.runOneTest("nestedGroupRefs2") } + @Test def test_nestedGroupRefs3(): Unit = { runner_02.runOneTest("nestedGroupRefs3") } + @Test def test_nestedGroupRefs4(): Unit = { runner_02.runOneTest("nestedGroupRefs4") } + @Test def test_nestedGroupRefs5(): Unit = { runner_02.runOneTest("nestedGroupRefs5") } @Test def test_hiddenGroupChoice(): Unit = { runner_02.runOneTest("hiddenGroupChoice") } @Test def test_hiddenGroupChoice2(): Unit = { runner_02.runOneTest("hiddenGroupChoice2") } @Test def test_hiddenGroupIgnoredProps(): Unit = {