You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@daffodil.apache.org by ji...@apache.org on 2022/12/27 19:39:07 UTC

[daffodil] branch main updated: Add emptyElementParsePolicy to main dfdl namespace.

This is an automated email from the ASF dual-hosted git repository.

jinterrante 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 abe36cb22 Add emptyElementParsePolicy to main dfdl namespace.
abe36cb22 is described below

commit abe36cb220ae389c86b040b8e05cfdf0f04de6aa
Author: Mike McGann <mm...@owlcyberdefense.com>
AuthorDate: Tue Dec 20 10:04:13 2022 -0500

    Add emptyElementParsePolicy to main dfdl namespace.
    
    The emptyElementParsePolicy is currently implemented as a property
    that is an extension to DFDL. As of DFDL 1.0, this property is now
    available in the main schema. This property has now been added and a
    deprecation message is emitted when the old property is used. The
    property value of 'treatAsMissing' has been renamed to 'treatAsAbsent'
    in DFDL 1.0.
    
    DAFFODIL-2496
---
 .../daffodil/dsom/DFDLFormatAnnotation.scala       |   1 +
 .../grammar/primitives/SequenceChild.scala         |   4 +-
 .../apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd |   3 +-
 .../schema/annotation/props/ByHandMixins.scala     |  21 ++--
 .../apache/daffodil/xsd/DFDL_part1_simpletypes.xsd |   7 ++
 .../apache/daffodil/xsd/DFDL_part2_attributes.xsd  |   8 +-
 .../resources/org/apache/daffodil/xsd/dafext.xsd   |   6 +-
 .../resources/org/apache/daffodil/xsd/dfdlx.xsd    |   6 +-
 .../processors/parsers/SequenceChildBases.scala    |   6 +-
 .../parsers/SequenceChildParseResultHelper.scala   |   2 +-
 .../test-suite/tresys-contributed/nilled.tdml      |   2 +-
 .../tresys-contributed/sepSuppression.tdml         |  87 +++++++++++--
 .../tresys-contributed/sepSuppression2.tdml        |   2 +-
 .../test-suite/tresys-contributed/unseparated.tdml |   2 +-
 .../choiceBranchRanges/choiceBranchKeyRanges.tdml  |   2 +-
 .../daffodil/extensions/lookAhead/lookAhead.tdml   |   2 +-
 .../apache/daffodil/section05/facets/NulChars.tdml |   2 +-
 .../section07/escapeScheme/escapeScenarios.tdml    |   2 +-
 .../daffodil/usertests/MultipartBody.dfdl.xsd      |   4 +-
 .../org/apache/daffodil/usertests/SepTests.tdml    | 138 ++++++++++++++-------
 .../apache/daffodil/usertests/TestSepTests.scala   |  12 +-
 21 files changed, 224 insertions(+), 95 deletions(-)

diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLFormatAnnotation.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLFormatAnnotation.scala
index 78c9241ff..f159c8387 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLFormatAnnotation.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLFormatAnnotation.scala
@@ -39,6 +39,7 @@ object DeprecatedProperty {
     DeprecatedProperty(XMLUtils.DFDL_NAMESPACE, "layerLength", "dfdlx:layerLength"),
     DeprecatedProperty(XMLUtils.DFDL_NAMESPACE, "layerLengthUnits", "dfdlx:layerLengthUnits"),
     DeprecatedProperty(XMLUtils.DFDL_NAMESPACE, "layerBoundaryMark", "dfdlx:layerBoundaryMark"),
+    DeprecatedProperty(XMLUtils.DFDLX_NAMESPACE, "emptyElementParsePolicy", "dfdl:emptyElementParsePolicy"),
     DeprecatedProperty(XMLUtils.EXT_NS_APACHE, "parseUnparsePolicy", "dfdlx:parseUnparsePolicy"),
     DeprecatedProperty(XMLUtils.EXT_NS_NCSA, "parseUnparsePolicy", "dfdlx:parseUnparsePolicy"))
 
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/SequenceChild.scala b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/SequenceChild.scala
index a83d66489..ee3415cf2 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/SequenceChild.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/SequenceChild.scala
@@ -438,11 +438,11 @@ class ScalarOrderedSequenceChild(sq: SequenceTermBase, term: Term, groupIndex: I
 
   /**
    * Must deal with nils, emptyness and string/hexBinary exceptional behavior
-   * including the behavior for dfdlx:emptyElementParsePolicy 'treatAsMissing' which special cases
+   * including the behavior for dfdl:emptyElementParsePolicy 'treatAsAbsent' which special cases
    * Required elements like scalars, iff they are emptyRep, emptyValueDelimiterPolicy,
    * nilValueDelimiterPolicy, complex elements that nillable, or fully defaultable.
    *
-   * So we have ((simpleStringHexBinary x (treatAsMissing, treatAsEmpty), simpleOther, complex) x (nillable, not) x
+   * So we have ((simpleStringHexBinary x (treatAsAbsent, treatAsEmpty), simpleOther, complex) x (nillable, not) x
    * 4 behaviors. That's 32 combinations. Let's start with fewer cases and more runtime
    * decisions, and specialize if we think it will help clarity or performance.
    */
diff --git a/daffodil-lib/src/main/resources/org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd b/daffodil-lib/src/main/resources/org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd
index d46072012..af7e00de7 100644
--- a/daffodil-lib/src/main/resources/org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd
+++ b/daffodil-lib/src/main/resources/org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd
@@ -103,7 +103,8 @@
       </dfdl:defineFormat>
       
       <dfdl:defineFormat name="GeneralFormat">
-        <dfdl:format ref="GeneralFormatOriginal" />
+        <dfdl:format ref="GeneralFormatOriginal"
+            emptyElementParsePolicy="treatAsEmpty"/>
       </dfdl:defineFormat>
         
       <dfdl:defineFormat name="GeneralFormatPortable">
diff --git a/daffodil-lib/src/main/scala/org/apache/daffodil/schema/annotation/props/ByHandMixins.scala b/daffodil-lib/src/main/scala/org/apache/daffodil/schema/annotation/props/ByHandMixins.scala
index 93f99ea54..6a994d579 100644
--- a/daffodil-lib/src/main/scala/org/apache/daffodil/schema/annotation/props/ByHandMixins.scala
+++ b/daffodil-lib/src/main/scala/org/apache/daffodil/schema/annotation/props/ByHandMixins.scala
@@ -430,9 +430,11 @@ trait TextStandardExponentRepMixin extends PropertyMixin {
  */
 sealed trait EmptyElementParsePolicy extends EmptyElementParsePolicy.Value
 object EmptyElementParsePolicy extends Enum[EmptyElementParsePolicy] {
-  case object TreatAsMissing extends EmptyElementParsePolicy
+  case object TreatAsMissing extends EmptyElementParsePolicy // deprecated
   case object TreatAsEmpty extends EmptyElementParsePolicy
-  override lazy val values = Array(TreatAsMissing, TreatAsEmpty)
+  case object TreatAsAbsent extends EmptyElementParsePolicy
+
+  override lazy val values = Array(TreatAsMissing, TreatAsEmpty, TreatAsAbsent) // deprecated: TreatAsMissing
 
   def apply(name: String, context: ThrowsSDE): EmptyElementParsePolicy = stringToEnum("emptyElementParsePolicy", name, context)
 }
@@ -454,7 +456,7 @@ trait EmptyElementParsePolicyMixin extends PropertyMixin {
 
   /**
    * Property determines whether Daffodil implements empty elements in a manner consistent with
-   * IBM DFDL (as of 2019-05-02), which has policy treatAsMissing, or implements what is
+   * IBM DFDL (as of 2019-05-02), which has policy treatAsAbsent, or implements what is
    * described in the DFDL spec., which is treatAsEmpty - if the syntax of
    * empty (or nullness) is matched, create an empty (or null) item, even if optional, unless
    * the element is entirely absent.
@@ -468,15 +470,10 @@ trait EmptyElementParsePolicyMixin extends PropertyMixin {
       // prop is not required AND not defined so use tunable value
       // but issue warning (which can be suppressed)
       val defaultEmptyElementParsePolicy = this.tunable.defaultEmptyElementParsePolicy
-      // This property is an extension, so we don't want to require users to
-      // add this property just to silence this warning, especially since the
-      // property might change in the future. So silently use a default without
-      // outputting a warning. We may want to turn this warning on when the
-      // property makes its way into the official DFDL spec.
-      //SDW(
-      //  WarnID.EmptyElementParsePolicyError,
-      //  "Property 'dfdlx:emptyElementParsePolicy' is required but not defined, using tunable '%s' by default.",
-      //  defaultEmptyElementParsePolicy)
+      SDW(
+        WarnID.EmptyElementParsePolicyError,
+        "Property 'dfdl:emptyElementParsePolicy' is required but not defined, using tunable '%s' by default.",
+        defaultEmptyElementParsePolicy)
       defaultEmptyElementParsePolicy
     }
   }
diff --git a/daffodil-propgen/src/main/resources/org/apache/daffodil/xsd/DFDL_part1_simpletypes.xsd b/daffodil-propgen/src/main/resources/org/apache/daffodil/xsd/DFDL_part1_simpletypes.xsd
index 9d6f351e3..1bc9a1df9 100644
--- a/daffodil-propgen/src/main/resources/org/apache/daffodil/xsd/DFDL_part1_simpletypes.xsd
+++ b/daffodil-propgen/src/main/resources/org/apache/daffodil/xsd/DFDL_part1_simpletypes.xsd
@@ -626,6 +626,13 @@
     </xsd:restriction>
   </xsd:simpleType>
 
+  <xsd:simpleType name="EmptyElementParsePolicyEnum">
+    <xsd:restriction base="xsd:string">
+      <xsd:enumeration value="treatAsEmpty" />
+      <xsd:enumeration value="treatAsAbsent" />
+    </xsd:restriction>
+  </xsd:simpleType>
+
   <!-- ============================================================= -->
   <!-- Simple types with DFDL Expression -->
   <!-- ============================================================= -->
diff --git a/daffodil-propgen/src/main/resources/org/apache/daffodil/xsd/DFDL_part2_attributes.xsd b/daffodil-propgen/src/main/resources/org/apache/daffodil/xsd/DFDL_part2_attributes.xsd
index 9f0b2a215..9fd404dd2 100644
--- a/daffodil-propgen/src/main/resources/org/apache/daffodil/xsd/DFDL_part2_attributes.xsd
+++ b/daffodil-propgen/src/main/resources/org/apache/daffodil/xsd/DFDL_part2_attributes.xsd
@@ -98,8 +98,9 @@
     <xsd:attribute name="bitOrder" type="dfdl:BitOrderEnum"/>
     <xsd:attribute ref="daf:parseUnparsePolicy"/> <!-- backwards compatibility -->
     <xsd:attribute ref="dfdlx:parseUnparsePolicy"/>
-    <xsd:attribute ref="dfdlx:emptyElementParsePolicy"/>
-      
+    <xsd:attribute name="emptyElementParsePolicy" type="dfdl:EmptyElementParsePolicyEnum"/>
+    <xsd:attribute ref="dfdlx:emptyElementParsePolicy"/> <!-- deprecated -->
+
     <xsd:attribute name="encoding"
       type="dfdl:EncodingEnum_Or_DFDLExpression" />
     <xsd:attribute name="utf16Width" type="dfdl:UTF16WidthEnum" />
@@ -539,6 +540,7 @@
       <xsd:enumeration value="bitOrder"/>
       <xsd:enumeration value="encoding" />
       <xsd:enumeration value="encodingErrorPolicy"/>
+      <xsd:enumeration value="emptyElementParsePolicy"/>
       <xsd:enumeration value="utf16Width" />
       <xsd:enumeration value="ignoreCase" />
 
@@ -641,6 +643,8 @@
       type="dfdl:EncodingEnum_Or_DFDLExpression" />
     <xsd:attribute form="qualified" name="encodingErrorPolicy"
       type="dfdl:EncodingErrorPolicyEnum" />
+    <xsd:attribute form="qualified" name="emptyElementParsePolicy"
+      type="dfdl:EmptyElementParsePolicyEnum" />
     <xsd:attribute form="qualified" name="utf16Width"
       type="dfdl:UTF16WidthEnum" />
     <xsd:attribute form="qualified" name="ignoreCase"
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 47439f44c..acd5d78e1 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
@@ -598,7 +598,11 @@
   </xs:element>
 
   <xs:simpleType name="TunableEmptyElementParsePolicy">
-    <xs:restriction base="dfdlx:EmptyElementParsePolicyEnum" />
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="treatAsEmpty" />
+      <xs:enumeration value="treatAsAbsent" />
+      <xs:enumeration value="treatAsMissing" /> <!-- deprecated -->
+    </xs:restriction>
   </xs:simpleType>
 
   <!--
diff --git a/daffodil-propgen/src/main/resources/org/apache/daffodil/xsd/dfdlx.xsd b/daffodil-propgen/src/main/resources/org/apache/daffodil/xsd/dfdlx.xsd
index f6037e787..395aed008 100644
--- a/daffodil-propgen/src/main/resources/org/apache/daffodil/xsd/dfdlx.xsd
+++ b/daffodil-propgen/src/main/resources/org/apache/daffodil/xsd/dfdlx.xsd
@@ -36,7 +36,7 @@
     <xs:restriction base="xs:string">
       <xs:enumeration value="dfdlx:alignmentKind" />
       <xs:enumeration value="dfdlx:choiceBranchKeyRanges" />
-      <xs:enumeration value="dfdlx:emptyElementParsePolicy"/>
+      <xs:enumeration value="dfdlx:emptyElementParsePolicy"/> <!-- deprecated -->
       <xs:enumeration value="dfdlx:inputTypeCalc"/>
       <xs:enumeration value="dfdlx:objectKind"/>
       <xs:enumeration value="dfdlx:outputTypeCalc"/>
@@ -94,11 +94,11 @@
     </xs:restriction>
   </xs:simpleType>
 
-  <xs:attribute name="emptyElementParsePolicy" type="dfdlx:EmptyElementParsePolicyEnum"/>
+  <xs:attribute name="emptyElementParsePolicy" type="dfdlx:EmptyElementParsePolicyEnum"/> <!-- deprecated -->
   <xs:simpleType name="EmptyElementParsePolicyEnum">
     <xs:restriction base="xs:string">
       <xs:enumeration value="treatAsEmpty" />
-      <xs:enumeration value="treatAsMissing" />
+      <xs:enumeration value="treatAsMissing" /> <!-- deprecated -->
     </xs:restriction>
   </xs:simpleType>
   
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SequenceChildBases.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SequenceChildBases.scala
index ad591f0ea..90d6f5eb6 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SequenceChildBases.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SequenceChildBases.scala
@@ -74,11 +74,11 @@ object ParseAttemptStatus {
    *
    * The EmptyRep for simpleTypes enables default values to be substituted at parse time.
    *
-   * For simple types xs:string and xs:hexBinary, the property dfdlx:emptyElementParsePolicy controls
+   * For simple types xs:string and xs:hexBinary, the property dfdl:emptyElementParsePolicy controls
    * whether the EmptyRep is allowed for strings and hexBinary. In required positions, when
-   * dfdlx:emptyElementParsePolicy is 'treatAsMissing', a required string/hexBinary that has EmptyRep
+   * dfdl:emptyElementParsePolicy is 'treatAsAbsent', a required string/hexBinary that has EmptyRep
    * causes a Parse Error, and an optional EmptyRep causes nothing to be added to the infoset (the empty string
-   * or hexBinary value is suppressed). When dfdlx:emptyElementParsePolicy is 'treatAsEmpty', a required
+   * or hexBinary value is suppressed). When dfdl:emptyElementParsePolicy is 'treatAsEmpty', a required
    * string/hexBinary with EmptyRep creates an empty string or zero-length byte array in the infoset.
    * An optional EmptyRep behaves differently depending on whether the EmptyRep is truly zero-length, or
    * dfdl:emptyValueDelimiterPolicy is such that EmptyRep is non-zero-length. When truly zero-length, no
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SequenceChildParseResultHelper.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SequenceChildParseResultHelper.scala
index 98bfa3057..8142b27ff 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SequenceChildParseResultHelper.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SequenceChildParseResultHelper.scala
@@ -274,7 +274,7 @@ trait ElementSequenceChildParseResultHelper
             pstate.schemaDefinitionError("Default values not implemented.")
           } else {
             emptyElementParsePolicy match {
-              case EmptyElementParsePolicy.TreatAsMissing => {
+              case EmptyElementParsePolicy.TreatAsMissing | EmptyElementParsePolicy.TreatAsAbsent => { // deprecated: TreatAsMissing
                 parser.PE(pstate, "Empty element not allowed for required element.")
                 ParseAttemptStatus.MissingItem
               }
diff --git a/daffodil-test-ibm1/src/test/resources/test-suite/tresys-contributed/nilled.tdml b/daffodil-test-ibm1/src/test/resources/test-suite/tresys-contributed/nilled.tdml
index f3873bc8d..e37855d42 100644
--- a/daffodil-test-ibm1/src/test/resources/test-suite/tresys-contributed/nilled.tdml
+++ b/daffodil-test-ibm1/src/test/resources/test-suite/tresys-contributed/nilled.tdml
@@ -38,7 +38,7 @@
 
   <tdml:defineConfig name="cfg_noEmptyElements">
     <daf:tunables>
-      <daf:defaultEmptyElementParsePolicy>treatAsMissing</daf:defaultEmptyElementParsePolicy>
+      <daf:defaultEmptyElementParsePolicy>treatAsAbsent</daf:defaultEmptyElementParsePolicy>
       <daf:suppressSchemaDefinitionWarnings>
         unsupportedAttributeFormDefault
         encodingErrorPolicyError
diff --git a/daffodil-test-ibm1/src/test/resources/test-suite/tresys-contributed/sepSuppression.tdml b/daffodil-test-ibm1/src/test/resources/test-suite/tresys-contributed/sepSuppression.tdml
index 72f893ec9..7bccbc536 100644
--- a/daffodil-test-ibm1/src/test/resources/test-suite/tresys-contributed/sepSuppression.tdml
+++ b/daffodil-test-ibm1/src/test/resources/test-suite/tresys-contributed/sepSuppression.tdml
@@ -36,12 +36,12 @@
       </daf:suppressSchemaDefinitionWarnings>
     </daf:tunables>
   </tdml:defineConfig>
-  
+
   <tdml:defineConfig name="cfg_noEmptyElements">
     <daf:tunables>
-      <daf:defaultEmptyElementParsePolicy>treatAsMissing</daf:defaultEmptyElementParsePolicy>
+      <daf:defaultEmptyElementParsePolicy>treatAsAbsent</daf:defaultEmptyElementParsePolicy>
       <daf:suppressSchemaDefinitionWarnings>
-        unsupportedAttributeFormDefault 
+        unsupportedAttributeFormDefault
         encodingErrorPolicyError
       </daf:suppressSchemaDefinitionWarnings>
     </daf:tunables>
@@ -209,7 +209,7 @@
           <record>
             <required1>a</required1>
             <!-- 
-              On Daffodil, because we are using dfdlx:emptyElementParsePolicy='treatAsMissing'
+              On Daffodil, because we are using dfdl:emptyElementParsePolicy='treatAsAbsent'
               This test should not create any empty-string-valued elements.
               That should be consistent with IBM DFDL behavior (as of 2019-05-04 version).              
             <positional2/>
@@ -247,7 +247,7 @@
         <ptg1>
           <record>
             <required1>a</required1>
-            <!-- dfdlx:emptyElementParsePolicy='treatAsMissing'
+            <!-- dfdl:emptyElementParsePolicy='treatAsAbsent'
               <positional2/>
               <positional3/>
             -->
@@ -257,7 +257,7 @@
           </record>
           <record>
             <required1>a</required1>
-            <!-- dfdlx:emptyElementParsePolicy='treatAsMissing'
+            <!-- dfdl:emptyElementParsePolicy='treatAsAbsent'
               <positional2/>
               <positional3/>
             -->
@@ -283,7 +283,7 @@
             <!-- 
               Because these are optional, and their dfdl:emptyValueDelimiterPolicy is 'none'
               an empty representation does not create an element.
-              This is true for dfdlx:emptyElementParsePolicy="treatAsEmpty".
+              This is true for dfdl:emptyElementParsePolicy="treatAsEmpty".
               If you want empty elements, there has to be a non-zero-length 
               syntax in the data stream
               <positional2/>
@@ -640,7 +640,69 @@
     </xs:element>
     
   </tdml:defineSchema>
-  
+
+  <!-- Same as s3 schema but emptyElementParsePolicy is now treatAsAbsent -->
+
+  <tdml:defineSchema name="s3_absent" elementFormDefault="unqualified">
+    <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd" />
+
+    <dfdl:format ref="ex:GeneralFormatPortable"
+                 lengthKind="delimited"
+                 occursCountKind="implicit"
+                 emptyElementParsePolicy="treatAsAbsent"/>
+
+    <!--
+      ptg3 explores spoiling the choice's potentially trailing by just having
+      a single branch that has required framing.
+     -->
+    <xs:element name="ptg3" dfdl:initiator="|">
+      <xs:complexType>
+        <xs:sequence dfdl:separator="">
+          <xs:element dfdl:occursCountKind="implicit" dfdl:terminator="|%WSP*;"
+                      maxOccurs="unbounded" name="record">
+            <xs:complexType>
+              <xs:sequence dfdl:separator="," dfdl:separatorSuppressionPolicy="trailingEmpty">
+                <xs:element name="required1" type="xs:string" />
+                <xs:element name="positional2" type="xs:string" minOccurs="0" /> <!-- never trailing due to choice -->
+                <xs:element name="positional3" type="xs:string" minOccurs="0" /> <!-- never trailing due to choice -->
+                <xs:choice>
+                  <!--
+                    choice is not trailing, because none of the choice branches are.
+                    (In general, it ought to be the last choice branch, otherwise
+                    finding zero length will cut off consideration of any branches after
+                    the first potentially trailing branch.)
+                   -->
+                  <xs:sequence>
+                    <xs:element name="positional4_n" type="xs:decimal"/>
+                  </xs:sequence>
+                  <xs:sequence>
+                    <xs:element name="positional4_s" type="xs:string" />
+                  </xs:sequence>
+                  <xs:sequence />
+                </xs:choice>
+                <!--
+                  Element potTrailing5 is potentially trailing because the sequence
+                  following it is a potentially trailing group.
+                 -->
+                <xs:element name="potTrailing5" type="xs:string" minOccurs="0"/>
+                <xs:sequence dfdl:separator="*" dfdl:separatorSuppressionPolicy="trailingEmpty">
+                  <!--
+                    This sequence is potentially trailing,
+                    If empty and trailing the comma for this group in the enclosing sequence may be omitted.
+                  -->
+                  <xs:element name="potTrailing6" type="xs:int" minOccurs="0" maxOccurs="3" />
+                </xs:sequence>
+                <xs:element name="potTrailing7" type="xs:string" minOccurs="0"/>
+                <xs:element name="potTrailing8" type="xs:string" minOccurs="0"/>
+              </xs:sequence>
+            </xs:complexType>
+          </xs:element>
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+
+  </tdml:defineSchema>
+
   <tdml:parserTestCase name="ptg3_2p_daf" root="ptg3" model="s3"
     description="Test of potentially trailing groups. Daffodil specific as it retains required empty string elements."
     roundTrip="none"
@@ -653,7 +715,7 @@
         <ex:ptg3>
           <record>
             <required1>a</required1>
-            <!-- empty string has no syntax, so even when dfdlx:emptyElementParsePolicy is 'treatAsEmpty'
+            <!-- empty string has no syntax, so even when dfdl:emptyElementParsePolicy is 'treatAsEmpty'
                  we still don't create optional empty string elements.
             <positional2/>
             <positional3/>
@@ -680,9 +742,8 @@
 
   </tdml:parserTestCase>
  
-  <tdml:parserTestCase name="ptg3_1p" root="ptg3" model="s3"
+  <tdml:parserTestCase name="ptg3_1p" root="ptg3" model="s3_absent"
     description="Test of potentially trailing groups."
-    config="cfg_noEmptyElements"
     roundTrip="none">
 
     <tdml:document><![CDATA[|a,,,,|a,,,,|]]></tdml:document>
@@ -692,12 +753,12 @@
         <ex:ptg3>
           <record>
             <required1>a</required1>
-            <!-- <positional4_s/> scalar, but is backtracked anyway by IBM DFDL, daffodil treatAsMissing mode. -->
+            <!-- <positional4_s/> scalar, but is backtracked anyway by IBM DFDL, daffodil treatAsAbsent mode. -->
             <!-- no empty string for positional5 -->
           </record>
           <record>
             <required1>a</required1>
-            <!-- <positional4_s/> scalar, but is backtracked anyway by IBM DFDL, daffodil treatAsMissing mode. -->
+            <!-- <positional4_s/> scalar, but is backtracked anyway by IBM DFDL, daffodil treatAsAbsent mode. -->
             <!-- no empty string for positional5 -->
           </record>
         </ex:ptg3>
diff --git a/daffodil-test-ibm1/src/test/resources/test-suite/tresys-contributed/sepSuppression2.tdml b/daffodil-test-ibm1/src/test/resources/test-suite/tresys-contributed/sepSuppression2.tdml
index bd9e3290c..a75ddec03 100644
--- a/daffodil-test-ibm1/src/test/resources/test-suite/tresys-contributed/sepSuppression2.tdml
+++ b/daffodil-test-ibm1/src/test/resources/test-suite/tresys-contributed/sepSuppression2.tdml
@@ -283,7 +283,7 @@
         <xs:sequence dfdl:separator="," dfdl:separatorSuppressionPolicy="anyEmpty">
           <xs:element name="foo" type="xs:string" dfdl:lengthKind="delimited" />
           <xs:element name="bar" type="xs:string" dfdl:lengthKind="delimited"
-            minOccurs="0" dfdl:occursCountKind="implicit" dfdlx:emptyElementParsePolicy="treatAsEmpty" />
+            minOccurs="0" dfdl:occursCountKind="implicit" dfdl:emptyElementParsePolicy="treatAsEmpty" />
         </xs:sequence>
       </xs:complexType>
     </xs:element>
diff --git a/daffodil-test-ibm1/src/test/resources/test-suite/tresys-contributed/unseparated.tdml b/daffodil-test-ibm1/src/test/resources/test-suite/tresys-contributed/unseparated.tdml
index e520ba06d..fb4fa0ac4 100644
--- a/daffodil-test-ibm1/src/test/resources/test-suite/tresys-contributed/unseparated.tdml
+++ b/daffodil-test-ibm1/src/test/resources/test-suite/tresys-contributed/unseparated.tdml
@@ -36,7 +36,7 @@
 
   <tdml:defineConfig name="cfg_noEmptyElements">
     <daf:tunables>
-      <daf:defaultEmptyElementParsePolicy>treatAsMissing</daf:defaultEmptyElementParsePolicy>
+      <daf:defaultEmptyElementParsePolicy>treatAsAbsent</daf:defaultEmptyElementParsePolicy>
       <daf:suppressSchemaDefinitionWarnings>
         unsupportedAttributeFormDefault
         encodingErrorPolicyError
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/extensions/choiceBranchRanges/choiceBranchKeyRanges.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/extensions/choiceBranchRanges/choiceBranchKeyRanges.tdml
index 1b9f2ee33..50b8dc417 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/extensions/choiceBranchRanges/choiceBranchKeyRanges.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/extensions/choiceBranchRanges/choiceBranchKeyRanges.tdml
@@ -29,7 +29,7 @@
     <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
     <dfdl:format ref="ex:GeneralFormat"
       lengthUnits="bits"
-      dfdlx:emptyElementParsePolicy="treatAsEmpty"
+      emptyElementParsePolicy="treatAsEmpty"
       representation="binary"
       />
 
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/extensions/lookAhead/lookAhead.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/extensions/lookAhead/lookAhead.tdml
index 30f2e6f13..351500324 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/extensions/lookAhead/lookAhead.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/extensions/lookAhead/lookAhead.tdml
@@ -28,7 +28,7 @@
     <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
     <dfdl:format ref="ex:GeneralFormat"
       lengthUnits="bits"
-      dfdlx:emptyElementParsePolicy="treatAsEmpty"
+      emptyElementParsePolicy="treatAsEmpty"
       />
 
     <dfdl:defineVariable name="myVar1" type="xs:integer" />
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section05/facets/NulChars.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/section05/facets/NulChars.tdml
index 6e2a41243..66d224e88 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section05/facets/NulChars.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section05/facets/NulChars.tdml
@@ -60,7 +60,7 @@
         -->
         <xs:element name="nz" type="xs:string" minOccurs="0" maxOccurs="0"
                     dfdl:lengthPattern='[^\x{00}]+' dfdl:lengthKind="pattern"
-                    dfdl:occursCountKind="parsed" dfdl:encoding="iso-8859-1" dfdlx:emptyElementParsePolicy="treatAsMissing">
+                    dfdl:occursCountKind="parsed" dfdl:encoding="iso-8859-1" dfdl:emptyElementParsePolicy="treatAsAbsent">
         </xs:element>
       </xs:sequence>
     </xs:complexType>
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section07/escapeScheme/escapeScenarios.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/section07/escapeScheme/escapeScenarios.tdml
index 7b3f9a356..96143b854 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section07/escapeScheme/escapeScenarios.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section07/escapeScheme/escapeScenarios.tdml
@@ -344,7 +344,7 @@
         <xs:sequence dfdl:separator="$;" dfdl:separatorPosition="infix">
           <xs:element name="x" type="xs:string" dfdl:escapeSchemeRef="tns:scenario2" />
           <xs:element name="y" type="xs:string" minOccurs="0" dfdl:escapeSchemeRef="tns:scenario2"
-            dfdlx:emptyElementParsePolicy="treatAsEmpty" />
+            dfdl:emptyElementParsePolicy="treatAsEmpty" />
         </xs:sequence>
       </xs:complexType>
     </xs:element>
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/usertests/MultipartBody.dfdl.xsd b/daffodil-test/src/test/resources/org/apache/daffodil/usertests/MultipartBody.dfdl.xsd
index 86230544f..70f2ff7d1 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/usertests/MultipartBody.dfdl.xsd
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/usertests/MultipartBody.dfdl.xsd
@@ -53,8 +53,8 @@
 				dfdl:terminator="--%CR;%LF;">
 				<xsd:element name="BodyPart" dfdl:lengthKind="delimited"
 					minOccurs="1" maxOccurs="unbounded" type="xsd:string"
-					dfdl:occursCountKind="implicit" 
-          dfdlx:emptyElementParsePolicy="treatAsEmpty" />
+					dfdl:occursCountKind="implicit"
+				 	dfdl:emptyElementParsePolicy="treatAsEmpty" />
 			</xsd:sequence>
 		</xsd:complexType>
 	</xsd:element>
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/usertests/SepTests.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/usertests/SepTests.tdml
index e338f1658..b2257d337 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/usertests/SepTests.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/usertests/SepTests.tdml
@@ -193,12 +193,7 @@
       ref="ex:GeneralFormatPortable"
       representation="text"
       lengthKind="delimited"
-      separatorPosition="infix"
-      dfdlx:emptyElementParsePolicy="treatAsEmpty"/><!-- remove extension proerty for IBM cross tests -->
-    <!--
-    Note: dfdlx:emptyElementParsePolicy should become regular DFDL emptyElementParsePolicy
-    once implemented in DAFFODIL-2496. The enum 'treatAsMissing' is renamed to 'treatAsAbsent'
-    -->
+      separatorPosition="infix"/>
 
     <xs:element name="file1">
       <xs:complexType>
@@ -271,25 +266,46 @@
     </tdml:infoset>
   </tdml:parserTestCase>
 
-  <!--
-  This schema identical to s3, except for the dfdlx:emptyElementParsePolicy is treatAsMissing
-  -->
+  <!-- Test for DAFFODIL-2499. empty strings should not be creating empty elements here. -->
+  <tdml:parserTestCase name="test_sep_ssp_never_3" root="file1" model="s3"
+                       implementations="ibm">
+    <tdml:document>madonna,,,,,,,,,</tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:file1>
+          <given-name>madonna</given-name>
+        </ex:file1>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="test_sep_ssp_never_4_ibm" root="file2" model="s3"
+                       implementations="ibm">
+    <tdml:document>madonna,,,,,,,,,</tdml:document>
+    <!--
+      When we cross test on IBM DFDL, this test passes, but the TDML runner doesn't
+      insist the error strings are found. Only that an error occurred.
+      -->
+    <tdml:errors>
+      <tdml:error>Parse Error</tdml:error>
+      <tdml:error>emptyElementParsePolicy</tdml:error>
+      <tdml:error>treatAsMissing</tdml:error> <!-- deprecated -->
+      <tdml:error>required</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
+
   <tdml:defineSchema name="s4" elementFormDefault="unqualified">
 
     <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
     <dfdl:format
-      ref="ex:GeneralFormatPortable"
-      representation="text"
-      lengthKind="delimited"
-      separatorPosition="infix"
-      dfdlx:emptyElementParsePolicy="treatAsMissing"/> <!-- remove extension proerty for IBM cross tests -->
-    <!--
-    Note: dfdlx:emptyElementParsePolicy should become regular DFDL emptyElementParsePolicy
-    once implemented in DAFFODIL-2496. The enum 'treatAsMissing' is renamed to 'treatAsAbsent'
-    -->
+            ref="ex:GeneralFormatPortable"
+            representation="text"
+            lengthKind="delimited"
+            separatorPosition="infix"
+            dfdlx:emptyElementParsePolicy="treatAsMissing"/>
 
     <!--
-    treatAsMissing should have no effect here, because everything is optional.
+    treatAsMissing should have no effect here, because everything is optional. (deprecated)
     -->
     <xs:element name="file1">
       <xs:complexType>
@@ -304,9 +320,7 @@
 
     <!-- Same, but has minOccurs=maxOccurs for the arrays.
      That makes all array elements "required"
-
-     treatAsMissing causes this to fail. Required empty non-defaultable is an error in that case.
-     (note: treatAsMissing will become treatAsAbsent DAFFODIL-2496)
+     treatAsMissing causes this to fail. Required empty non-defaultable is an error in that case. (deprecated)
      -->
     <xs:element name="file2">
       <xs:complexType>
@@ -321,33 +335,73 @@
 
   </tdml:defineSchema>
 
-  <!-- Test for DAFFODIL-2499. empty strings should not be creating empty elements here. -->
-  <tdml:parserTestCase name="test_sep_ssp_never_3" root="file1" model="s4"
-                       implementations="ibm">
+  <tdml:parserTestCase name="test_sep_ssp_never_4_daffodil" root="file2" model="s4"
+                       implementations="daffodil">
     <tdml:document>madonna,,,,,,,,,</tdml:document>
-    <tdml:infoset>
-      <tdml:dfdlInfoset>
-        <ex:file1>
-          <given-name>madonna</given-name>
-        </ex:file1>
-      </tdml:dfdlInfoset>
-    </tdml:infoset>
+    <tdml:warnings>
+      <tdml:warning>emptyElementParsePolicy is deprecated</tdml:warning>
+      <tdml:warning>Use dfdl:emptyElementParsePolicy</tdml:warning>
+    </tdml:warnings>
+    <tdml:errors>
+      <tdml:error>Parse Error</tdml:error>
+      <tdml:error>Empty element not allowed</tdml:error>
+      <tdml:error>required</tdml:error>
+    </tdml:errors>
   </tdml:parserTestCase>
 
-  <tdml:parserTestCase name="test_sep_ssp_never_4" root="file2" model="s4"
-                       implementations="ibm">
-    <tdml:document>madonna,,,,,,,,,</tdml:document>
+  <!--
+  This schema identical to s3, except for the emptyElementParsePolicy is treatAsAbsent
+  -->
+  <tdml:defineSchema name="s5" elementFormDefault="unqualified">
+
+    <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+    <dfdl:format
+            ref="ex:GeneralFormatPortable"
+            representation="text"
+            lengthKind="delimited"
+            separatorPosition="infix"
+            emptyElementParsePolicy="treatAsAbsent"/>
+
     <!--
-      When we cross test on IBM DFDL, this test passes, but the TDML runner doesn't
-      insist the error strings are found. Only that an error occurred.
-      -->
+    treatAsAbsent should have no effect here, because everything is optional.
+    -->
+    <xs:element name="file1">
+      <xs:complexType>
+        <xs:sequence dfdl:separator="," dfdl:separatorPosition="infix"
+                     dfdl:separatorSuppressionPolicy="never">
+          <xs:element name="given-name" type="xs:string" minOccurs="0" maxOccurs="3"/>
+          <xs:element name="surname" type="xs:string" minOccurs="0"/>
+          <xs:element name="phone" type="xs:string" minOccurs="0" maxOccurs="6"/>
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+
+    <!-- Same, but has minOccurs=maxOccurs for the arrays.
+     That makes all array elements "required"
+
+     treatAsAbsent causes this to fail. Required empty non-defaultable is an error in that case.
+     -->
+    <xs:element name="file2">
+      <xs:complexType>
+        <xs:sequence dfdl:separator="," dfdl:separatorPosition="infix"
+                     dfdl:separatorSuppressionPolicy="never">
+          <xs:element name="given-name" type="xs:string" minOccurs="3" maxOccurs="3"/>
+          <xs:element name="surname" type="xs:string"/>
+          <xs:element name="phone" type="xs:string" minOccurs="6" maxOccurs="6"/>
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+
+  </tdml:defineSchema>
+
+  <tdml:parserTestCase name="test_sep_ssp_never_5" root="file2" model="s5"
+                       implementations="daffodil">
+    <tdml:document>madonna,,,,,,,,,</tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>emptyElementParsePolicy</tdml:error>
-      <tdml:error>treatAsMissing</tdml:error><!-- will change to treatAsAbsent DAFFODIL-2496 -->
+      <tdml:error>Empty element not allowed</tdml:error>
       <tdml:error>required</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
-
-</tdml:testSuite>
\ No newline at end of file
+</tdml:testSuite>
diff --git a/daffodil-test/src/test/scala/org/apache/daffodil/usertests/TestSepTests.scala b/daffodil-test/src/test/scala/org/apache/daffodil/usertests/TestSepTests.scala
index a60568012..81ccf50e7 100644
--- a/daffodil-test/src/test/scala/org/apache/daffodil/usertests/TestSepTests.scala
+++ b/daffodil-test/src/test/scala/org/apache/daffodil/usertests/TestSepTests.scala
@@ -23,7 +23,7 @@ import org.junit.AfterClass
 
 object TestSepTests {
   val testDir = "/org/apache/daffodil/usertests/"
-  val runner = Runner(testDir, "SepTests.tdml")
+  val runner: Runner = Runner(testDir, "SepTests.tdml")
 
   @AfterClass def shutDown(): Unit = {
     runner.reset
@@ -58,10 +58,10 @@ class TestSepTests {
   // Add daffodil to implementations to see the erroneous daffodil behavior.
   @Test def test_sep_ssp_never_3(): Unit = { runner.runOneTest("test_sep_ssp_never_3") }
 
-  // DAFFODIL-2496 - implement DFDL official emptyElementParsePolicy property
-  // Note: this test isn't commented out, because it works for IBM DFDL in cross testing
-  // The TDML for this test just has it disabled for the daffodil implementation.
-  // Add daffodil to implementations to see the erroneous daffodil behavior.
-  @Test def test_sep_ssp_never_4(): Unit = { runner.runOneTest("test_sep_ssp_never_4") }
+  @Test def test_sep_ssp_never_4_ibm(): Unit = { runner.runOneTest("test_sep_ssp_never_4_ibm") }
+
+  @Test def test_sep_ssp_never_4_daffodil(): Unit = { runner.runOneTest("test_sep_ssp_never_4_daffodil") }
+
+  @Test def test_sep_ssp_never_5(): Unit = { runner.runOneTest("test_sep_ssp_never_5") }
 
 }