diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/ModelGroup.scala b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/ModelGroup.scala
index 2e4db8b3f4..b97efb1e5c 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/ModelGroup.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/ModelGroup.scala
@@ -341,6 +341,22 @@ abstract class ModelGroup protected (index: Int)
}
}
+ final lazy val elementChildrenInNonHiddenContext: Seq[ElementBase] =
+ LV('elementChildrenInNonHiddenContext) {
+ val ebs = groupMembers
+ .filter {
+ case gr: GroupRef => !gr.isHidden
+ case _ => true
+ }
+ .flatMap { gm =>
+ gm match {
+ case eb: ElementBase => Seq(eb)
+ case gb: ModelGroup => gb.elementChildren
+ }
+ }
+ ebs
+ }.value
+
final lazy val elementChildren: Seq[ElementBase] = LV('elementChildren) {
val gms = groupMembers
val echls = gms.flatMap { gm =>
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SequenceGroup.scala b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SequenceGroup.scala
index 5defef394c..68978d5bf6 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SequenceGroup.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SequenceGroup.scala
@@ -103,6 +103,7 @@ abstract class SequenceGroupTermBase(xml: Node, lexicalParent: SchemaComponent,
requiredEvaluationsIfActivated(checkIfValidUnorderedSequence)
requiredEvaluationsIfActivated(checkIfNonEmptyAndDiscrimsOrAsserts)
+ requiredEvaluationsIfActivated(checkIfMultipleChildrenWithSameName)
protected def apparentXMLChildren: Seq[Node]
@@ -181,7 +182,7 @@ abstract class SequenceGroupTermBase(xml: Node, lexicalParent: SchemaComponent,
if (!isOrdered) {
checkMembersAreAllElementOrElementRef
checkMembersHaveValidOccursCountKind
- checkMembersHaveUniqueNamesInNamespaces
+ checkUnorderedSequenceMembersHaveUniqueNamesInNamespaces
}
}
@@ -215,20 +216,34 @@ abstract class SequenceGroupTermBase(xml: Node, lexicalParent: SchemaComponent,
}
}
- private lazy val checkMembersHaveUniqueNamesInNamespaces: Unit = {
- val childrenGroupedByQName = groupMembers.groupBy { gm =>
- // previous checks should ensure that all group members are either local
- // elements or element references
- Assert.invariant(gm.isInstanceOf[ElementBase])
- gm.asInstanceOf[ElementBase].namedQName
- }
- childrenGroupedByQName.foreach { case (qname, children) =>
- if (children.length > 1) {
+ private lazy val checkUnorderedSequenceMembersHaveUniqueNamesInNamespaces: Unit = {
+ // previous checks should ensure that all element children for unordered sequences are either local
+ // elements or element references
+ elementChildrenInNonHiddenContext
+ .groupBy(_.namedQName)
+ .filter(_._2.length > 1)
+ .values
+ .foreach { children =>
children.head.SDE(
"Two or more members of an unordered sequence have the same name and the same namespace"
)
}
- }
+ }
+
+ private lazy val checkIfMultipleChildrenWithSameName: Unit = {
+ elementChildrenInNonHiddenContext
+ .groupBy(_.name)
+ .filter(_._2.length > 1)
+ .values
+ .foreach { children =>
+ children.head.SDW(
+ WarnID.MultipleChildElementsWithSameName,
+ "Two or more members of the sequence have the same name. " +
+ "Since not all infosets support namespaces or siblings with the same name, " +
+ "this could cause issues. QNames are: %s",
+ children.map(c => c.namedQName).mkString(", ")
+ )
+ }
}
final lazy val isOrdered: Boolean = this.sequenceKind match {
diff --git a/daffodil-propgen/src/main/resources/org/apache/daffodil/xsd/dafext.xsd b/daffodil-propgen/src/main/resources/org/apache/daffodil/xsd/dafext.xsd
index 69ea3fdbb5..befb240b68 100644
--- a/daffodil-propgen/src/main/resources/org/apache/daffodil/xsd/dafext.xsd
+++ b/daffodil-propgen/src/main/resources/org/apache/daffodil/xsd/dafext.xsd
@@ -736,6 +736,7 @@
+
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 7707d14547..1b809da886 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
@@ -1237,6 +1237,7 @@
+
@@ -1353,6 +1354,12 @@
+
+ Two or more members
+ same name
+ ex:inty
+
+
+
+ Two or more members
+ same name
+ ex:inty
+
+
+
+ Two or more members
+ same name
+ ex:inty
+
+
@@ -1651,4 +1670,115 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+ 2
+ 3
+ 4
+
+
+
+
+
+ Schema Definition Warning
+ same name
+ AmbigElt
+
+
+
+
+
+
+
+
+
+
+ 1
+
+
+ 2
+
+
+ 3
+
+
+ 4
+
+
+ 5
+
+
+ 6
+
+
+ 7
+
+
+ 8
+
+
+
+
+
+
+
+ Schema Definition Warning
+ same name
+ {}e1
+ u:e1
+
+
+
+
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section15/choice_groups/choice2736.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/section15/choice_groups/choice2736.tdml
new file mode 100644
index 0000000000..a3e90a6a80
--- /dev/null
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section15/choice_groups/choice2736.tdml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Schema Definition Error
+ AmbigElt
+ Unique Particle Attribution
+
+
+
+
+
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 873eb6e7b9..56d47d8056 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
@@ -147,4 +147,12 @@ class TestSequenceGroups {
// @Test def test_delimiterScanning_03() { runner_01.runOneTest("delimiterScanning_03") }
@Test def test_hiddenGroupIVC(): Unit = { runner_02.runOneTest("hiddenGroupIVC") }
+
+ // DAFFODIL-2736
+ @Test def test_multipleElemSameName() = {
+ runner_02.runOneTest("multipleElemSameName")
+ }
+ @Test def test_multipleElemSameNameDifferentNamespaces() = {
+ runner_02.runOneTest("multipleElemSameNameDifferentNamespaces")
+ }
}
diff --git a/daffodil-test/src/test/scala/org/apache/daffodil/section15/choice_groups/TestChoice2.scala b/daffodil-test/src/test/scala/org/apache/daffodil/section15/choice_groups/TestChoice2.scala
index 647ddec52a..3cd9025302 100644
--- a/daffodil-test/src/test/scala/org/apache/daffodil/section15/choice_groups/TestChoice2.scala
+++ b/daffodil-test/src/test/scala/org/apache/daffodil/section15/choice_groups/TestChoice2.scala
@@ -28,11 +28,13 @@ object TestChoice2 {
val runner = Runner(testDir, "choice1765.tdml")
val runner1773 = Runner(testDir, "choice1773.tdml")
val runner2162 = Runner(testDir, "choice2162.tdml")
+ val runner2736 = Runner(testDir, "choice2736.tdml")
@AfterClass def shutDown(): Unit = {
runner.reset
runner1773.reset
runner2162.reset
+ runner2736.reset
}
}
@@ -63,4 +65,8 @@ class TestChoice2 {
runner2162.runOneTest("choiceArrayDirectDispatch1")
}
+ // DAFFODIL-2736
+ @Test def test_choiceAmbiguousUPA() = {
+ runner2736.runOneTest("choiceAmbiguousUPA")
+ }
}