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

olabusayo 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 7db9e4e4c De-personalize Diagnostic File URLs in Compiled Schemas
7db9e4e4c is described below

commit 7db9e4e4cda3b52875ab64c820df8e0855822610
Author: olabusayoT <[email protected]>
AuthorDate: Fri Aug 4 10:58:51 2023 -0400

    De-personalize Diagnostic File URLs in Compiled Schemas
    
    - pass on java.io.File to URISchemaSource as well as URI; update usages
    - update diagnostics to remove systemid but keep cause, line number and 
column number
    - remove maxParentDirectoriesForDiagnostics tunable and 
diagnosticsStripLocationInfo tdml attribute as it's no longer used and has been 
replaced with diagnosticFile
    - return URISchemaSource from resolveSchemaLocation and 
fileResourceURIConverter
    - update URISchemaSource constructor to accept 2 arguments instead of tuple
    - add XercesSchemaFileLocation class which uses xercesError and 
schemaFileLocation to create more complete schemaFileLocation
    - if we're using a fakeSchemaDocXML, overwrite the diagnosticFile returned 
from resolveSchemaLocation to use the xmlSchemaDocument.diagnosticFile
    - use Paths.resolveSibling for diagnosticFilepath resolution against 
context diagnosticFile
    - set diagnosticFile to empty string for DaffodilXMLLoader with comment 
explaining why
    - create uriToDiagnosticFile function with heuristic for jar/file/null 
scheme with separate handling
    - pass in fake context in cwd to resolveSchemaLocation call from main
    - clarification comments
    - update tests to remove paths with unix path separators
    - update/add tests
    
    DAFFODIL-2195
---
 .../main/scala/org/apache/daffodil/cli/Main.scala  | 68 +++++++++++++---------
 .../daffodil/cli/cliTest/TestCLISaveParser.scala   | 16 +++++
 .../apache/daffodil/core/compiler/Compiler.scala   |  2 +-
 .../apache/daffodil/core/dsom/DFDLSchemaFile.scala | 31 ++++++++--
 .../org/apache/daffodil/core/dsom/IIBase.scala     | 22 +++++--
 .../org/apache/daffodil/core/dsom/Import.scala     | 10 +++-
 .../core/dsom/SchemaComponentFactory.scala         |  5 +-
 .../SchemaComponentIncludesAndImportsMixin.scala   |  4 ++
 .../dsom/SchemaDocIncludesAndImportsMixin.scala    | 10 ++++
 .../org/apache/daffodil/core/dsom/SchemaSet.scala  |  4 +-
 .../daffodil/core/dsom/TestDsomCompiler.scala      | 14 +++--
 .../daffodil/core/processor/TestSAXUtils.scala     | 68 ++++++++++++++++++----
 .../org/apache/daffodil/core/util/TestUtils.scala  |  3 +-
 .../core/xml/TestXMLLoaderWithLocation.scala       |  8 ++-
 .../scala/org/apache/daffodil/japi/Daffodil.scala  |  3 +-
 .../org/apache/daffodil/example/TestJavaAPI.java   |  1 -
 .../resources/org/apache/daffodil/xsd/tdml.xsd     | 15 -----
 .../apache/daffodil/lib/api/DaffodilConfig.scala   |  9 ++-
 .../daffodil/lib/api/DaffodilSchemaSource.scala    | 52 ++++++++++++-----
 .../org/apache/daffodil/lib/api/Diagnostic.scala   | 21 -------
 .../lib/exceptions/SchemaFileLocatable.scala       | 63 +++++++++++++-------
 .../scala/org/apache/daffodil/lib/util/Misc.scala  | 12 ++++
 .../daffodil/lib/xml/DaffodilXMLLoader.scala       | 15 ++++-
 .../org/apache/daffodil/lib/xml/XMLUtils.scala     | 42 ++++++++++---
 .../resources/org/apache/daffodil/xsd/dafext.xsd   | 13 -----
 .../apache/daffodil/propGen/TunableGenerator.scala |  7 ++-
 .../externalvars/ExternalVariablesLoader.scala     |  5 +-
 .../daffodil/runtime1/processors/RuntimeData.scala |  2 +-
 .../scala/org/apache/daffodil/sapi/Daffodil.scala  |  3 +-
 .../org/apache/daffodil/tdml/TDMLRunner.scala      | 51 ++++++----------
 .../daffodil/section00/general/TestResolver.tdml   |  1 -
 .../section00/general/disallowDocTypes.tdml        |  4 --
 .../SchemaDefinitionErrors.tdml                    | 65 +--------------------
 .../daffodil/section06/namespaces/namespaces.tdml  | 14 ++---
 .../dfdl_expressions/expression_fail.tdml          |  1 -
 .../apache/daffodil/infoset/TestStringAsXml.scala  |  4 +-
 .../schema_definition_errors/TestSDE.scala         |  8 ---
 37 files changed, 386 insertions(+), 290 deletions(-)

diff --git a/daffodil-cli/src/main/scala/org/apache/daffodil/cli/Main.scala 
b/daffodil-cli/src/main/scala/org/apache/daffodil/cli/Main.scala
index e18a14be3..dcf8214b2 100644
--- a/daffodil-cli/src/main/scala/org/apache/daffodil/cli/Main.scala
+++ b/daffodil-cli/src/main/scala/org/apache/daffodil/cli/Main.scala
@@ -227,7 +227,7 @@ class CLIConf(arguments: Array[String], stdout: 
PrintStream, stderr: PrintStream
 
   implicit def rootNSConverter = 
org.rogach.scallop.singleArgConverter[RefQName](qnameConvert _)
 
-  implicit def fileResourceURIConverter = singleArgConverter[URI]((s: String) 
=> {
+  implicit def fileResourceURIConverter = 
singleArgConverter[URISchemaSource]((s: String) => {
     val optResolved =
       try {
         val uri =
@@ -256,19 +256,22 @@ class CLIConf(arguments: Array[String], stdout: 
PrintStream, stderr: PrintStream
             }
           }
         // At this point we have a valid URI, which could be absolute or 
relative, with relative
-        // URIs resolved from the current working directory. We can convert 
this to a string and
-        // pass it to resolveSchemaLocation to find the actual file or resource
-        val cwd = Paths.get("").toUri
-        XMLUtils.resolveSchemaLocation(uri.toString, Some(cwd))
+        // URIs resolved from the current working directory. We create a fake 
contextPath that represents
+        // a fake file in the current working directory and pass that as the 
contextSource to the
+        // resolveSchemaLocation function to find the actual file or resource. 
This is necessary because
+        // resolveSchemaLocation expects a context that is a file for 
diagnostic purposes.
+        val contextPath = Paths.get("fakeContext.dfdl.xsd")
+        val contextSource = URISchemaSource(contextPath.toFile, 
contextPath.toUri)
+        XMLUtils.resolveSchemaLocation(uri.toString, Some(contextSource))
       } catch {
         case _: Exception => throw new Exception(s"Could not find file or 
resource $s")
       }
     optResolved match {
-      case Some((uri, relToAbs)) => {
+      case Some((uriSchemaSource, relToAbs)) => {
         if (relToAbs) {
           Logger.log.warn(s"Found relative path on classpath absolutely, did 
you mean /$s")
         }
-        uri
+        uriSchemaSource
       }
       case None => {
         throw new Exception(s"Could not find file or resource $s")
@@ -377,7 +380,11 @@ class CLIConf(arguments: Array[String], stdout: 
PrintStream, stderr: PrintStream
         "Root element to use. Can be prefixed with {namespace}. Must be a 
top-level element. Defaults to first top-level element of DFDL schema.",
     )
     val schema =
-      opt[URI]("schema", argName = "file", descr = "DFDL schema to use to 
create parser")(
+      opt[URISchemaSource](
+        "schema",
+        argName = "file",
+        descr = "DFDL schema to use to create parser",
+      )(
         fileResourceURIConverter,
       )
     val stream = toggle(
@@ -488,7 +495,11 @@ class CLIConf(arguments: Array[String], stdout: 
PrintStream, stderr: PrintStream
         "Root element to use. Can be prefixed with {namespace}. Must be a 
top-level element. Defaults to first top-level element of DFDL schema.",
     )
     val schema =
-      opt[URI]("schema", argName = "file", descr = "DFDL schema to use to 
create parser")(
+      opt[URISchemaSource](
+        "schema",
+        argName = "file",
+        descr = "DFDL schema to use to create parser",
+      )(
         fileResourceURIConverter,
       )
     val stream = toggle(
@@ -576,7 +587,7 @@ class CLIConf(arguments: Array[String], stdout: 
PrintStream, stderr: PrintStream
       descr =
         "Root element to use. Can be prefixed with {namespace}. Must be a 
top-level element. Defaults to first top-level element of DFDL schema.",
     )
-    val schema = opt[URI](
+    val schema = opt[URISchemaSource](
       "schema",
       required = true,
       argName = "file",
@@ -685,7 +696,11 @@ class CLIConf(arguments: Array[String], stdout: 
PrintStream, stderr: PrintStream
         "Root element to use. Can be prefixed with {namespace}. Must be a 
top-level element. Defaults to first top-level element of DFDL schema.",
     )
     val schema =
-      opt[URI]("schema", argName = "file", descr = "DFDL schema to use to 
create parser")(
+      opt[URISchemaSource](
+        "schema",
+        argName = "file",
+        descr = "DFDL schema to use to create parser",
+      )(
         fileResourceURIConverter,
       )
     val threads = opt[Int](
@@ -774,7 +789,7 @@ class CLIConf(arguments: Array[String], stdout: 
PrintStream, stderr: PrintStream
         descr =
           "Root element to use. Can be prefixed with {namespace}. Must be a 
top-level element. Defaults to first top-level element of DFDL schema.",
       )
-      val schema = opt[URI](
+      val schema = opt[URISchemaSource](
         "schema",
         required = true,
         argName = "file",
@@ -820,7 +835,7 @@ class CLIConf(arguments: Array[String], stdout: 
PrintStream, stderr: PrintStream
       descr =
         "Output file to write the encoded/decoded file to. If not given or is 
-, data is written to stdout.",
     )
-    val schema = opt[URI](
+    val schema = opt[URISchemaSource](
       "schema",
       argName = "file",
       descr = "DFDL schema to use for schema aware encoding/decoding.",
@@ -1018,7 +1033,7 @@ class Main(
   }
 
   def createProcessorFromSchema(
-    schema: URI,
+    schemaSource: URISchemaSource,
     rootNS: Option[RefQName],
     path: Option[String],
     tunablesMap: Map[String, String],
@@ -1039,7 +1054,6 @@ class Main(
     // to also include the call to pf.onPath. (which is the last phase
     // of compilation, where it asks for the parser)
     //
-    val schemaSource = URISchemaSource(schema)
     val res = Timer.getResult(
       "compiling", {
         val processorFactory = compiler.compileSource(schemaSource)
@@ -1067,7 +1081,7 @@ class Main(
   }
 
   def createGeneratorFromSchema(
-    schema: URI,
+    schemaSource: URISchemaSource,
     rootNS: Option[RefQName],
     tunables: Map[String, String],
     language: String,
@@ -1081,7 +1095,6 @@ class Main(
       }
     }
 
-    val schemaSource = URISchemaSource(schema)
     val cg = Timer.getResult(
       "compiling", {
         val processorFactory = compiler.compileSource(schemaSource)
@@ -1164,11 +1177,10 @@ class Main(
               case Some(file) => new FileOutputStream(file)
             }
 
-            val infosetType = parseOpts.infosetType.toOption.get
             val infosetHandler = InfosetType.getInfosetHandler(
-              parseOpts.infosetType.toOption.get,
+              parseOpts.infosetType(),
               processor,
-              parseOpts.schema.toOption,
+              parseOpts.schema.map(_.uri).toOption,
               forPerformance = false,
             )
 
@@ -1340,11 +1352,10 @@ class Main(
               }
             }
 
-            val infosetType = performanceOpts.infosetType.toOption.get
             val infosetHandler = InfosetType.getInfosetHandler(
-              infosetType,
+              performanceOpts.infosetType(),
               processor,
-              performanceOpts.schema.toOption,
+              performanceOpts.schema.map(_.uri).toOption,
               forPerformance = true,
             )
 
@@ -1505,11 +1516,10 @@ class Main(
             var keepUnparsing = maybeScanner.isEmpty || 
maybeScanner.get.hasNext
             var exitCode = ExitCode.Success
 
-            val infosetType = unparseOpts.infosetType.toOption.get
             val infosetHandler = InfosetType.getInfosetHandler(
-              unparseOpts.infosetType.toOption.get,
+              unparseOpts.infosetType(),
               processor,
-              unparseOpts.schema.toOption,
+              unparseOpts.schema.map(_.uri).toOption,
               forPerformance = false,
             )
 
@@ -1806,7 +1816,11 @@ class Main(
 
         val exiFactory: Option[EXIFactory] =
           try {
-            Some(EXIInfosetHandler.createEXIFactory(exiOpts.schema.toOption))
+            Some(
+              EXIInfosetHandler.createEXIFactory(
+                exiOpts.schema.map(_.uri).toOption,
+              ),
+            )
           } catch {
             case e: EXIException => {
               Logger.log.error(
diff --git 
a/daffodil-cli/src/test/scala/org/apache/daffodil/cli/cliTest/TestCLISaveParser.scala
 
b/daffodil-cli/src/test/scala/org/apache/daffodil/cli/cliTest/TestCLISaveParser.scala
index d37187cf3..34148166d 100644
--- 
a/daffodil-cli/src/test/scala/org/apache/daffodil/cli/cliTest/TestCLISaveParser.scala
+++ 
b/daffodil-cli/src/test/scala/org/apache/daffodil/cli/cliTest/TestCLISaveParser.scala
@@ -318,4 +318,20 @@ class TestCLISaveParser {
     }
   }
 
+  /**
+   * Attempted to save-parser an invalid schema so we can check the diagnostic 
error for leaked information
+   */
+  @Test def test_CLI_Saving_SaveParser_error(): Unit = {
+    val schema = path(
+      "daffodil-sapi/src/test/resources/test/sapi/mySchema6.dfdl.xsd",
+    )
+
+    withTempFile { parser =>
+      runCLI(args"save-parser -s $schema $parser") { cli =>
+        cli.expectErr("[error]")
+        cli.expectErr(s"Schema context:  Location line 32 column 74 in 
${schema.normalize()}")
+      }(ExitCode.UnableToCreateProcessor)
+    }
+  }
+
 }
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/compiler/Compiler.scala 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/compiler/Compiler.scala
index 75ec86408..16365d68e 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/compiler/Compiler.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/compiler/Compiler.scala
@@ -325,7 +325,7 @@ class Compiler private (
     optRootName: Option[String] = None,
     optRootNamespace: Option[String] = None,
   ): ProcessorFactory = {
-    val source = URISchemaSource(file.toURI)
+    val source = URISchemaSource(file, file.toURI)
     compileSource(source, optRootName, optRootNamespace)
   }
 
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/DFDLSchemaFile.scala
 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/DFDLSchemaFile.scala
index 9873fffb9..3bf3b8ba5 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/DFDLSchemaFile.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/DFDLSchemaFile.scala
@@ -17,11 +17,14 @@
 
 package org.apache.daffodil.core.dsom
 
+import java.io.File
+
 import org.apache.daffodil.core.dsom.IIUtils._
 import org.apache.daffodil.lib.api.Diagnostic
 import org.apache.daffodil.lib.api._
 import org.apache.daffodil.lib.exceptions.Assert
 import org.apache.daffodil.lib.exceptions.SchemaFileLocation
+import org.apache.daffodil.lib.exceptions.XercesSchemaFileLocation
 import org.apache.daffodil.lib.util.Logger
 import org.apache.daffodil.lib.util.Misc
 import org.apache.daffodil.lib.xml.DaffodilXMLLoader
@@ -45,16 +48,30 @@ class DFDLSchemaFileLoadErrorHandler(schemaFileLocation: 
SchemaFileLocation)
   private def loaderErrors = loaderErrors_
   private def loaderWarnings = loaderWarnings_
 
-  private def loaderSDEs: Seq[Diagnostic] = loaderErrors.map {
-    new SchemaDefinitionError(schemaFileLocation, "Error loading schema due to 
%s", _)
+  private def loaderSDEs: Seq[Diagnostic] = loaderErrors.map { err =>
+    val errMessage = err.getMessage
+    // we create a new SchemaFileLocation (xsfl) because the Xerces error has 
line, column and file info that
+    // the original schemaFileLocation that's passed in doesn't contain, so we 
can pass in this more
+    // complete SchemaFileLocation
+    val xsfl = new XercesSchemaFileLocation(err, schemaFileLocation)
+    new SchemaDefinitionError(
+      xsfl,
+      "Error loading schema due to %s",
+      errMessage,
+    )
   }
 
-  private def loaderSDWs: Seq[Diagnostic] = loaderWarnings.map {
+  private def loaderSDWs: Seq[Diagnostic] = loaderWarnings.map { w =>
+    val warnMessage = w.getMessage
+    // we create a new SchemaFileLocation (xsfl) because the Xerces error has 
line and column info that
+    // the original schemaFileLocation that's passed in doesn't contain, so we 
can pass in this more
+    // complete SchemaFileLocation
+    val xsfl = new XercesSchemaFileLocation(w, schemaFileLocation)
     new SchemaDefinitionWarning(
       WarnID.XmlParser,
-      schemaFileLocation,
+      xsfl,
       "Warning loading schema due to %s",
-      _,
+      warnMessage,
     )
   }
 
@@ -139,7 +156,9 @@ final class DFDLSchemaFile(
 
   override lazy val uriString = schemaSource.uriForLoading.toString
 
-  override protected lazy val diagnosticDebugNameImpl = 
schemaSource.uriForLoading.toString
+  override lazy val diagnosticFile: File = schemaSource.diagnosticFile
+
+  override protected lazy val diagnosticDebugNameImpl = diagnosticFile.getPath
 
   lazy val diagnosticChildren =
     Nil // no recursive descent. We just want the loader's validation errors.
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/IIBase.scala 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/IIBase.scala
index 8fe32ecf6..4922926de 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/IIBase.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/IIBase.scala
@@ -26,6 +26,7 @@ import org.apache.daffodil.core.dsom.IIUtils._
 import org.apache.daffodil.lib.api.DaffodilSchemaSource
 import org.apache.daffodil.lib.api.URISchemaSource
 import org.apache.daffodil.lib.api.WarnID
+import org.apache.daffodil.lib.exceptions.Assert
 import org.apache.daffodil.lib.util.Delay
 import org.apache.daffodil.lib.util.Misc
 import org.apache.daffodil.lib.xml.NS
@@ -195,15 +196,28 @@ abstract class IIBase(
   protected final lazy val resolvedSchemaLocation: 
Option[DaffodilSchemaSource] =
     LV('resolvedSchemaLocation) {
       val res = schemaLocationProperty.flatMap { slText =>
-        val enclosingSchemaURI = schemaFile.map { _.schemaSource.uriForLoading 
}
-        val optURI = XMLUtils.resolveSchemaLocation(slText, enclosingSchemaURI)
-        val optSource = optURI.map { case (uri, relToAbs) =>
+        val enclosingSchemaSource = schemaFile.map { sf =>
+          sf.schemaSource
+        }
+        val optURISchemaSource =
+          XMLUtils.resolveSchemaLocation(slText, enclosingSchemaSource)
+        val optSource = optURISchemaSource.map { case (uriSchemaSource, 
relToAbs) =>
           schemaDefinitionWarningWhen(
             WarnID.DeprecatedRelativeSchemaLocation,
             relToAbs,
             s"Resolving relative schemaLocations absolutely is deprecated. Did 
you mean /$slText",
           )
-          URISchemaSource(uri)
+          // if isBootStrapSD is true, we assume we are using the 
fakeXMLSchemaDocument, which means
+          // we will be passing in and receiving back an absolute 
diagnosticFilepath from resolveSchemaLocation.
+          // In just this case, we want to ignore that absolute filepath and 
use the diagnosticFilepath
+          // from main, which is the XMLSchemaDocument diagnosticFilepath
+          val finalUriSchemaSource = if (xmlSchemaDocument.isBootStrapSD) {
+            Assert.invariant(enclosingSchemaSource.isEmpty)
+            URISchemaSource(xmlSchemaDocument.diagnosticFile, 
uriSchemaSource.uri)
+          } else {
+            uriSchemaSource
+          }
+          finalUriSchemaSource
         }
         optSource
       }
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/Import.scala 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/Import.scala
index 453ece025..2391e8d21 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/Import.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/Import.scala
@@ -25,6 +25,7 @@ import org.apache.daffodil.lib.api.DaffodilSchemaSource
 import org.apache.daffodil.lib.api.URISchemaSource
 import org.apache.daffodil.lib.exceptions.Assert
 import org.apache.daffodil.lib.util.Logger
+import org.apache.daffodil.lib.util.Misc
 import org.apache.daffodil.lib.xml._
 
 /**
@@ -98,10 +99,13 @@ final class Import(importNode: Node, xsd: 
XMLSchemaDocument, seenArg: IIMap)
         None
       }
       case Some(ns) => {
-        val uri = resolver.resolveURI(ns.toString)
-        if (uri == null) None
+        val uriString = resolver.resolveURI(ns.toString)
+        if (uriString == null) None
         else {
-          val res = URISchemaSource(URI.create(uri))
+          val uri = URI.create(uriString)
+          val dfp = Misc.uriToDiagnosticFile(uri)
+          val res =
+            URISchemaSource(dfp, uri)
           Some(res)
         }
       }
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SchemaComponentFactory.scala
 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SchemaComponentFactory.scala
index a9b21b669..714a3972c 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SchemaComponentFactory.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SchemaComponentFactory.scala
@@ -17,10 +17,10 @@
 
 package org.apache.daffodil.core.dsom
 
+import java.io.File
 import scala.xml.NamespaceBinding
 
 import org.apache.daffodil.core.dsom.walker.CommonContextView
-import org.apache.daffodil.lib.api.DaffodilTunables
 import org.apache.daffodil.lib.exceptions.SchemaFileLocatable
 import org.apache.daffodil.lib.xml.NS
 import org.apache.daffodil.lib.xml.XMLUtils
@@ -31,8 +31,6 @@ trait SchemaFileLocatableImpl extends SchemaFileLocatable { 
self: SchemaComponen
   def schemaFile: Option[DFDLSchemaFile]
   def optLexicalParent: Option[SchemaComponent]
 
-  def tunables: DaffodilTunables = self.tunable
-
   /**
    * Annotations can contain expressions, so we need to be able to compile 
them.
    *
@@ -76,6 +74,7 @@ trait CommonContextMixin extends NestingLexicalMixin with 
CommonContextView {
   }
   final def xmlSchemaDocument: XMLSchemaDocument = optXMLSchemaDocument.get
   def uriString: String = optLexicalParent.get.uriString
+  def diagnosticFile: File = optLexicalParent.get.diagnosticFile
 
   def xml: scala.xml.Node
 
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SchemaComponentIncludesAndImportsMixin.scala
 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SchemaComponentIncludesAndImportsMixin.scala
index 09e4be462..77b6c9def 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SchemaComponentIncludesAndImportsMixin.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SchemaComponentIncludesAndImportsMixin.scala
@@ -17,6 +17,8 @@
 
 package org.apache.daffodil.core.dsom
 
+import java.io.File
+
 /**
  * Mixin for all SchemaComponents
  */
@@ -35,4 +37,6 @@ trait SchemaComponentIncludesAndImportsMixin extends 
CommonContextMixin {
     xmlSchemaDocument.uriString
   }.toOption.getOrElse(orElseURL)
 
+  override def diagnosticFile: File = xmlSchemaDocument.diagnosticFile
+
 }
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SchemaDocIncludesAndImportsMixin.scala
 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SchemaDocIncludesAndImportsMixin.scala
index 13c00515b..ed709a984 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SchemaDocIncludesAndImportsMixin.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SchemaDocIncludesAndImportsMixin.scala
@@ -22,6 +22,7 @@ import scala.xml.NodeSeq
 
 import org.apache.daffodil.core.dsom.IIUtils._
 import org.apache.daffodil.lib.equality._
+import org.apache.daffodil.lib.exceptions.Assert
 import org.apache.daffodil.lib.xml.NS
 import org.apache.daffodil.lib.xml.NoNamespace
 
@@ -144,6 +145,15 @@ trait SchemaDocIncludesAndImportsMixin { self: 
XMLSchemaDocument =>
     this.uriStringFromAttribute.getOrElse("file:unknown")
   }
 
+  override lazy val diagnosticFile = if (self.schemaFile.isDefined) {
+    self.schemaFile.get.diagnosticFile
+  } else {
+    // in the case of a boostrap/fake schema document, schemaFile can be None, 
so we want
+    // to grab the diagnostic of the first schema in the schemaSet
+    Assert.invariant(self.isBootStrapSD)
+    self.schemaSet.diagnosticFile
+  }
+
   protected def seenBefore: IIMap
 
   // val iiXML: Node = xml // override in SchemaSet
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SchemaSet.scala 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SchemaSet.scala
index 6a76ae2f6..696f0268d 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SchemaSet.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SchemaSet.scala
@@ -96,7 +96,7 @@ final class SchemaSet private (
   val schemaSource: DaffodilSchemaSource,
   val shouldValidateDFDLSchemas: Boolean,
   val checkAllTopLevel: Boolean,
-  override val tunables: DaffodilTunables,
+  val tunables: DaffodilTunables,
 ) extends SchemaComponentImpl(<schemaSet/>, None)
   with SchemaSetIncludesAndImportsMixin
   with SchemaSetGrammarMixin {
@@ -139,6 +139,8 @@ final class SchemaSet private (
    */
   override lazy val uriString: String = schemaSource.uriForLoading.toString
 
+  override lazy val diagnosticFile: File = schemaSource.diagnosticFile
+
   override def warn(th: Diagnostic) = oolagWarn(th)
 
   override def error(th: Diagnostic) = oolagError(th)
diff --git 
a/daffodil-core/src/test/scala/org/apache/daffodil/core/dsom/TestDsomCompiler.scala
 
b/daffodil-core/src/test/scala/org/apache/daffodil/core/dsom/TestDsomCompiler.scala
index 26830d58f..1cd63a2f5 100644
--- 
a/daffodil-core/src/test/scala/org/apache/daffodil/core/dsom/TestDsomCompiler.scala
+++ 
b/daffodil-core/src/test/scala/org/apache/daffodil/core/dsom/TestDsomCompiler.scala
@@ -17,6 +17,7 @@
 
 package org.apache.daffodil.core.dsom
 
+import java.nio.file.Paths
 import scala.xml.Node
 import scala.xml.Utility
 import scala.xml.XML
@@ -225,6 +226,8 @@ class TestDsomCompiler {
     assertTrue(elem.isInstanceOf[LocalElementDecl])
   }
 
+  private val exampleOfMostDFDLConstructsXML = 
"/test/example-of-most-dfdl-constructs.dfdl.xml"
+
   @Test def test3(): Unit = {
     // Newer versions of the scala-xml library changed the XML.load() function
     // so that it does not ignore comments/processing instructions. This causes
@@ -233,7 +236,8 @@ class TestDsomCompiler {
     // does remove comments and what is normally used by Daffodil) to load the
     // XML to a Scala XML Node.
     val source = URISchemaSource(
-      
Misc.getRequiredResource("/test/example-of-most-dfdl-constructs.dfdl.xml"),
+      Paths.get(exampleOfMostDFDLConstructsXML).toFile,
+      Misc.getRequiredResource(exampleOfMostDFDLConstructsXML),
     )
     val loader = new DaffodilXMLLoader(null)
     val testSchema = loader.load(source, None)
@@ -340,7 +344,7 @@ class TestDsomCompiler {
 
   @Test def test4(): Unit = {
     val testSchema =
-      
XML.load(Misc.getRequiredResource("/test/example-of-most-dfdl-constructs.dfdl.xml").toURL)
+      XML.load(Misc.getRequiredResource(exampleOfMostDFDLConstructsXML).toURL)
 
     val sset = SchemaSet(testSchema)
     val Seq(sch) = sset.schemas
@@ -450,7 +454,7 @@ class TestDsomCompiler {
 
   @Test def test_simpleType_base_combining(): Unit = {
     val testSchema =
-      
XML.load(Misc.getRequiredResource("/test/example-of-most-dfdl-constructs.dfdl.xml").toURL)
+      XML.load(Misc.getRequiredResource(exampleOfMostDFDLConstructsXML).toURL)
 
     val sset = SchemaSet(testSchema)
     val Seq(sch) = sset.schemas
@@ -502,7 +506,7 @@ class TestDsomCompiler {
 
   @Test def test_group_references(): Unit = {
     val testSchema =
-      
XML.load(Misc.getRequiredResource("/test/example-of-most-dfdl-constructs.dfdl.xml").toURL)
+      XML.load(Misc.getRequiredResource(exampleOfMostDFDLConstructsXML).toURL)
 
     val sset = SchemaSet(testSchema)
     val Seq(sch) = sset.schemas
@@ -679,7 +683,7 @@ class TestDsomCompiler {
 
   @Test def test_element_references(): Unit = {
     val testSchema =
-      
XML.load(Misc.getRequiredResource("/test/example-of-most-dfdl-constructs.dfdl.xml").toURL)
+      XML.load(Misc.getRequiredResource(exampleOfMostDFDLConstructsXML).toURL)
 
     val sset = SchemaSet(testSchema)
     val Seq(sch) = sset.schemas
diff --git 
a/daffodil-core/src/test/scala/org/apache/daffodil/core/processor/TestSAXUtils.scala
 
b/daffodil-core/src/test/scala/org/apache/daffodil/core/processor/TestSAXUtils.scala
index 71eee346b..84b38a804 100644
--- 
a/daffodil-core/src/test/scala/org/apache/daffodil/core/processor/TestSAXUtils.scala
+++ 
b/daffodil-core/src/test/scala/org/apache/daffodil/core/processor/TestSAXUtils.scala
@@ -20,6 +20,7 @@ package org.apache.daffodil.core.processor
 import java.io.ByteArrayOutputStream
 import java.io.OutputStream
 import java.io.OutputStreamWriter
+import java.nio.file.Paths
 import scala.xml.Elem
 
 import org.apache.daffodil.core.compiler.Compiler
@@ -58,10 +59,20 @@ object TestSAXUtils {
 
   lazy val loader = new DaffodilXMLLoader()
 
+  lazy val qualifiedWithNestedSchemasFilePath =
+    "/test/example_nested_namespaces_qualified.dfdl.xsd"
   lazy val qualifiedWithNestedSchemasFile =
-    
Misc.getRequiredResource("/test/example_nested_namespaces_qualified.dfdl.xsd")
+    Misc.getRequiredResource(qualifiedWithNestedSchemasFilePath)
   lazy val qualifiedWithNestedSchemasElem: Elem =
-    loader.load(URISchemaSource(qualifiedWithNestedSchemasFile), 
None).asInstanceOf[Elem]
+    loader
+      .load(
+        URISchemaSource(
+          Paths.get(qualifiedWithNestedSchemasFilePath).toFile,
+          qualifiedWithNestedSchemasFile,
+        ),
+        None,
+      )
+      .asInstanceOf[Elem]
   lazy val dpQualifiedWithNestedSchemas: DataProcessor = testDataProcessor(
     qualifiedWithNestedSchemasElem,
   )
@@ -132,10 +143,19 @@ object TestSAXUtils {
   lazy val nillableElementExpectedString: String = 
nillableElementExpectedInfoset.toString()
   lazy val nillableElementData: String = "^.-3.*4.7"
 
+  private val unqualifiedNoNamespacesFilePath = 
"/test/example_no_targetnamespace.dfdl.xsd"
   lazy val unqualifiedNoNamespacesFile =
-    Misc.getRequiredResource("/test/example_no_targetnamespace.dfdl.xsd")
+    Misc.getRequiredResource(unqualifiedNoNamespacesFilePath)
   lazy val unqualifiedNoNamespacesElem: Elem =
-    loader.load(URISchemaSource(unqualifiedNoNamespacesFile), 
None).asInstanceOf[Elem]
+    loader
+      .load(
+        URISchemaSource(
+          Paths.get(unqualifiedNoNamespacesFilePath).toFile,
+          unqualifiedNoNamespacesFile,
+        ),
+        None,
+      )
+      .asInstanceOf[Elem]
 
   /**
    * For an unqualified schemas with no targetnamespace and no default 
namespace, which means its
@@ -158,10 +178,20 @@ object TestSAXUtils {
     unqualifiedNoNamespacesExpectedInfoset.toString()
   lazy val unqualifiedNoNamespacesData: String = "world.no.^.tea"
 
+  lazy val unqualifiedWithNestedQualifiedFilePath =
+    "/test/example_nested_namespaces_unqualified.dfdl.xsd"
   lazy val unqualifiedWithNestedQualifiedFile =
-    
Misc.getRequiredResource("/test/example_nested_namespaces_unqualified.dfdl.xsd")
+    Misc.getRequiredResource(unqualifiedWithNestedQualifiedFilePath)
   lazy val unqualifiedWithNestedQualifiedElem: Elem =
-    loader.load(URISchemaSource(unqualifiedWithNestedQualifiedFile), 
None).asInstanceOf[Elem]
+    loader
+      .load(
+        URISchemaSource(
+          Paths.get(unqualifiedWithNestedQualifiedFilePath).toFile,
+          unqualifiedWithNestedQualifiedFile,
+        ),
+        None,
+      )
+      .asInstanceOf[Elem]
 
   /**
    * For an unqualified schemas with a targetnamespace and no default 
namespace, which means its
@@ -197,10 +227,20 @@ object TestSAXUtils {
     unqualifiedWithNestedQualifiedExpectedInfoset.toString()
   lazy val unqualifiedWithNestedQualifiedData: String = "hello.^.bye"
 
+  private val qualifiedWithDefaultNamespaceFilePath =
+    "/test/example_c02_targetnamespace_qualified.dfdl.xsd"
   lazy val qualifiedWithDefaultNamespaceFile =
-    
Misc.getRequiredResource("/test/example_c02_targetnamespace_qualified.dfdl.xsd")
+    Misc.getRequiredResource(qualifiedWithDefaultNamespaceFilePath)
   lazy val qualifiedWithDefaultNamespaceElem: Elem =
-    loader.load(URISchemaSource(qualifiedWithDefaultNamespaceFile), 
None).asInstanceOf[Elem]
+    loader
+      .load(
+        URISchemaSource(
+          Paths.get(qualifiedWithDefaultNamespaceFilePath).toFile,
+          qualifiedWithDefaultNamespaceFile,
+        ),
+        None,
+      )
+      .asInstanceOf[Elem]
   lazy val dpQualifiedWithDefaultNamespaceSchemas: DataProcessor = 
testDataProcessor(
     qualifiedWithDefaultNamespaceElem,
   )
@@ -213,11 +253,19 @@ object TestSAXUtils {
     qualifiedWithDefaultNamespaceExpectedInfoset.toString()
   lazy val qualifiedWithDefaultNamespaceData: String = "hello"
 
+  private val qualifiedWithDefaultAndNestedSchemasFilePath =
+    "/test/example_nested_namespaces_qualified_with_default.dfdl.xsd"
   lazy val qualifiedWithDefaultAndNestedSchemasFile =
-    
Misc.getRequiredResource("/test/example_nested_namespaces_qualified_with_default.dfdl.xsd")
+    Misc.getRequiredResource(qualifiedWithDefaultAndNestedSchemasFilePath)
   lazy val qualifiedWithDefaultAndNestedSchemasElem: Elem =
     loader
-      .load(URISchemaSource(qualifiedWithDefaultAndNestedSchemasFile), None)
+      .load(
+        URISchemaSource(
+          Paths.get(qualifiedWithDefaultAndNestedSchemasFilePath).toFile,
+          qualifiedWithDefaultAndNestedSchemasFile,
+        ),
+        None,
+      )
       .asInstanceOf[Elem]
   lazy val dpQualifiedWithDefaultAndNestedSchemas: DataProcessor = 
testDataProcessor(
     qualifiedWithDefaultAndNestedSchemasElem,
diff --git 
a/daffodil-core/src/test/scala/org/apache/daffodil/core/util/TestUtils.scala 
b/daffodil-core/src/test/scala/org/apache/daffodil/core/util/TestUtils.scala
index 30dcc965f..2c205fe2a 100644
--- a/daffodil-core/src/test/scala/org/apache/daffodil/core/util/TestUtils.scala
+++ b/daffodil-core/src/test/scala/org/apache/daffodil/core/util/TestUtils.scala
@@ -24,6 +24,7 @@ import java.io.InputStream
 import java.nio.channels.Channels
 import java.nio.channels.ReadableByteChannel
 import java.nio.channels.WritableByteChannel
+import java.nio.file.Paths
 import scala.collection.mutable.ArrayBuffer
 import scala.util.Try
 import scala.xml._
@@ -314,7 +315,7 @@ object TestUtils {
     val nullChannel = java.nio.channels.Channels.newChannel(nos)
     val compiler = Compiler()
     val uri = Misc.getRequiredResource(resourcePathString)
-    val schemaSource = URISchemaSource(uri)
+    val schemaSource = URISchemaSource(Paths.get(resourcePathString).toFile, 
uri)
     val theTry = Timer.getResult(compileAndSave(compiler, schemaSource, 
nullChannel))
     theTry.get
   }
diff --git 
a/daffodil-core/src/test/scala/org/apache/daffodil/core/xml/TestXMLLoaderWithLocation.scala
 
b/daffodil-core/src/test/scala/org/apache/daffodil/core/xml/TestXMLLoaderWithLocation.scala
index 6cd670b8a..a4b5e28c2 100644
--- 
a/daffodil-core/src/test/scala/org/apache/daffodil/core/xml/TestXMLLoaderWithLocation.scala
+++ 
b/daffodil-core/src/test/scala/org/apache/daffodil/core/xml/TestXMLLoaderWithLocation.scala
@@ -37,7 +37,9 @@ class TestXMLLoaderWithLocation {
       using(new java.io.FileWriter(tmpXMLFileName)) { fw =>
         fw.write(testXML.toString())
       }
-      val res = URISchemaSource(new File(tmpXMLFileName).toURI)
+      val tmpXMLFile = new File(tmpXMLFileName)
+      val res =
+        URISchemaSource(tmpXMLFile, tmpXMLFile.toURI)
       val eh = new BasicErrorHandler
       val node = (new DaffodilXMLLoader(eh)).load(res, None, 
addPositionAttributes = true)
       assertTrue(node.toString.toLowerCase.contains("dafint:file"))
@@ -69,7 +71,9 @@ class TestXMLLoaderWithLocation {
       using(new java.io.FileWriter(tmpXMLFileName)) { fw =>
         fw.write(testXML.toString())
       }
-      val res = URISchemaSource(new File(tmpXMLFileName).toURI)
+      val tmpXMLFile = new File(tmpXMLFileName)
+      val res =
+        URISchemaSource(tmpXMLFile, tmpXMLFile.toURI)
       val eh = new BasicErrorHandler
       val node = (new DaffodilXMLLoader(eh)).load(
         res,
diff --git 
a/daffodil-japi/src/main/scala/org/apache/daffodil/japi/Daffodil.scala 
b/daffodil-japi/src/main/scala/org/apache/daffodil/japi/Daffodil.scala
index ae33e22e1..75dcf2db4 100644
--- a/daffodil-japi/src/main/scala/org/apache/daffodil/japi/Daffodil.scala
+++ b/daffodil-japi/src/main/scala/org/apache/daffodil/japi/Daffodil.scala
@@ -38,6 +38,7 @@ import org.apache.daffodil.lib.api.{ DataLocation => 
SDataLocation }
 import org.apache.daffodil.lib.api.{ Diagnostic => SDiagnostic }
 import org.apache.daffodil.lib.api.{ LocationInSchemaFile => 
SLocationInSchemaFile }
 import org.apache.daffodil.lib.api.{ WithDiagnostics => SWithDiagnostics }
+import org.apache.daffodil.lib.util.Misc
 import org.apache.daffodil.lib.xml.DFDLCatalogResolver
 import org.apache.daffodil.lib.xml.XMLUtils
 import org.apache.daffodil.runtime1.api.DFDL.{
@@ -165,7 +166,7 @@ class Compiler private[japi] (private var sCompiler: 
SCompiler) {
    */
   @throws(classOf[java.io.IOException])
   def compileSource(uri: URI, rootName: String, rootNamespace: String): 
ProcessorFactory = {
-    val source = URISchemaSource(uri)
+    val source = URISchemaSource(Misc.uriToDiagnosticFile(uri), uri)
     val pf = sCompiler.compileSource(source, Option(rootName), 
Option(rootNamespace))
     new ProcessorFactory(pf)
   }
diff --git 
a/daffodil-japi/src/test/java/org/apache/daffodil/example/TestJavaAPI.java 
b/daffodil-japi/src/test/java/org/apache/daffodil/example/TestJavaAPI.java
index 4ba616953..1ad7b38b8 100644
--- a/daffodil-japi/src/test/java/org/apache/daffodil/example/TestJavaAPI.java
+++ b/daffodil-japi/src/test/java/org/apache/daffodil/example/TestJavaAPI.java
@@ -982,7 +982,6 @@ public class TestJavaAPI {
 
         org.apache.daffodil.japi.Compiler c = Daffodil.compiler();
 
-        java.io.File extVarFile = 
getResource("/test/japi/external_vars_1.xml");
         java.io.File schemaFile = 
getResource("/test/japi/mySchemaWithVars.dfdl.xsd");
         ProcessorFactory pf = c.compileFile(schemaFile);
         DataProcessor dp = pf.onPath("/");
diff --git a/daffodil-lib/src/main/resources/org/apache/daffodil/xsd/tdml.xsd 
b/daffodil-lib/src/main/resources/org/apache/daffodil/xsd/tdml.xsd
index d46450f5d..5a9c157e3 100644
--- a/daffodil-lib/src/main/resources/org/apache/daffodil/xsd/tdml.xsd
+++ b/daffodil-lib/src/main/resources/org/apache/daffodil/xsd/tdml.xsd
@@ -184,21 +184,6 @@
     <attribute name="unsupported" type="xs:boolean" use="optional" 
default="false"/>
     <attribute name="validation" type="tns:validationType" use="optional"/>
     <attribute name="implementations" type="tns:implementationsType" 
use="optional"/>
-    <attribute name="diagnosticsStripLocationInfo" type="xs:boolean" 
use="optional" default="true">
-      <annotation>
-        <documentation>We strip the file info from the diagnostics to prevent 
false
-          positive matches against the test case's error and warning strings
-          coming from file/dir names.
-
-          As there are tests that look for correct file/dir names, those
-          tests will need to NOT strip them and can do so by setting the
-          test flag to false.
-
-          This is only for purposes of comparing error/warning strings
-          to the diagnostic messages. Users would always see, displayed,
-          the full diagnostic messages.</documentation>
-      </annotation>
-    </attribute>
 
   </attributeGroup>
 
diff --git 
a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/api/DaffodilConfig.scala 
b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/api/DaffodilConfig.scala
index 05e9b7ab5..c8b076176 100644
--- 
a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/api/DaffodilConfig.scala
+++ 
b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/api/DaffodilConfig.scala
@@ -22,6 +22,7 @@ import scala.xml.Elem
 import scala.xml.Node
 
 import org.apache.daffodil.lib.externalvars.Binding
+import org.apache.daffodil.lib.util.Misc
 import org.apache.daffodil.lib.xml.DaffodilXMLLoader
 import org.apache.daffodil.lib.xml.NS
 import org.apache.daffodil.lib.xml.XMLUtils
@@ -66,9 +67,13 @@ object DaffodilConfig {
     }
   }
 
-  def fromURI(uri: URI) = fromSchemaSource(URISchemaSource(uri))
+  def fromURI(uri: URI) = fromSchemaSource(
+    URISchemaSource(Misc.uriToDiagnosticFile(uri), uri),
+  )
 
-  def fromFile(file: File) = fromURI(file.toURI)
+  def fromFile(file: File) = fromSchemaSource(
+    URISchemaSource(file, file.toURI),
+  )
 
 }
 
diff --git 
a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/api/DaffodilSchemaSource.scala
 
b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/api/DaffodilSchemaSource.scala
index b4ca3caa8..1179115b7 100644
--- 
a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/api/DaffodilSchemaSource.scala
+++ 
b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/api/DaffodilSchemaSource.scala
@@ -58,24 +58,30 @@ sealed trait DaffodilSchemaSource {
    * False otherwise.
    */
   def isXSD: Boolean
+
+  /**
+   * Diagnostic file path associated with this schema source
+   */
+  def diagnosticFile: File
 }
 
 object URISchemaSource {
-  def apply(fileOrResource: URI) = {
-    new URISchemaSource(fileOrResource)
+  def apply(diagnosticFile: File, uri: URI): URISchemaSource = {
+    new URISchemaSource(diagnosticFile, uri)
   }
 }
 
-class URISchemaSource protected (val fileOrResource: URI) extends 
DaffodilSchemaSource {
+class URISchemaSource protected (diagnosticFilepath: File, val uri: URI)
+  extends DaffodilSchemaSource {
 
   override def equals(other: Any) = other match {
-    case oth: URISchemaSource => this.fileOrResource == oth.fileOrResource
+    case oth: URISchemaSource => this.uri == oth.uri
     case _ => false
   }
 
-  override def hashCode() = fileOrResource.hashCode()
+  override def hashCode() = uri.hashCode()
 
-  private lazy val url = fileOrResource.toURL
+  private lazy val url = uri.toURL
 
   final def isXSD = isXSD_
 
@@ -96,7 +102,7 @@ class URISchemaSource protected (val fileOrResource: URI) 
extends DaffodilSchema
     val ext = uriString.split("\\.").last
     val isXSDExt = (ext == "xsd")
     try {
-      val path = Paths.get(fileOrResource)
+      val path = Paths.get(uri)
       val f = path.toFile()
       (true, isXSDExt, f, f.lastModified())
     } catch {
@@ -108,11 +114,13 @@ class URISchemaSource protected (val fileOrResource: URI) 
extends DaffodilSchema
   override def newInputSource() = {
     fileModTime // demand this so we have it recorded
     val is = new InputSource(url.openStream())
-    is.setSystemId(fileOrResource.toString)
+    is.setSystemId(uri.toString)
     is
   }
 
-  override def uriForLoading = fileOrResource
+  override def uriForLoading = uri
+
+  override def diagnosticFile: File = diagnosticFilepath
 
   /**
    * @return True if this URI is for a file, other URI is for a file
@@ -158,17 +166,19 @@ class InputStreamSchemaSource(
     inSrc
   }
   override def uriForLoading = tempURI
+
+  override def diagnosticFile: File = tempSchemaFile
 }
 
 protected sealed abstract class NodeSchemaSourceBase(
   node: Node,
   nameHint: String,
   tmpDir: Option[File],
-) extends URISchemaSource({
-    val tempSchemaFile = XMLUtils.convertNodeToTempFile(node, tmpDir.orNull, 
nameHint)
-    val tempURI = tempSchemaFile.toURI
-    tempURI
-  }) {
+  tempSchemaFileFromNode: File,
+) extends URISchemaSource(
+    tempSchemaFileFromNode,
+    tempSchemaFileFromNode.toURI,
+  ) {
 
   def blameName: String
 
@@ -180,7 +190,12 @@ protected sealed abstract class NodeSchemaSourceBase(
 }
 
 case class UnitTestSchemaSource(node: Node, nameHint: String, optTmpDir: 
Option[File] = None)
-  extends NodeSchemaSourceBase(node, nameHint, optTmpDir) {
+  extends NodeSchemaSourceBase(
+    node,
+    nameHint,
+    optTmpDir,
+    XMLUtils.convertNodeToTempFile(node, optTmpDir.orNull, nameHint),
+  ) {
   override val blameName =
     if (nameHint != "") "unittest:" + nameHint
     else uriForLoading.toString
@@ -191,6 +206,11 @@ case class UnitTestSchemaSource(node: Node, nameHint: 
String, optTmpDir: Option[
  * which in order to be able to validate repeatedly and such, is written to a 
temp file.
  */
 case class EmbeddedSchemaSource(node: Node, nameHint: String, optTmpDir: 
Option[File] = None)
-  extends NodeSchemaSourceBase(node, nameHint, optTmpDir) {
+  extends NodeSchemaSourceBase(
+    node,
+    nameHint,
+    optTmpDir,
+    XMLUtils.convertNodeToTempFile(node, optTmpDir.orNull, nameHint),
+  ) {
   override val blameName = nameHint
 }
diff --git 
a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/api/Diagnostic.scala 
b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/api/Diagnostic.scala
index 0da0c86af..c3d98b16a 100644
--- a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/api/Diagnostic.scala
+++ b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/api/Diagnostic.scala
@@ -256,27 +256,6 @@ trait LocationInSchemaFile {
   def fileDescription: String
 
   def locationDescription: String
-
-  def limitMaxParentDirectories(
-    uriString: String,
-    maxParentDirectoriesForDiagnostics: Int,
-  ): String = {
-    // works for both windows and unix
-    val splitter = "/"
-    val tokens = uriString.split(splitter)
-    val reducedTokens = tokens
-      // we want to get just the filename plus the max number of directories
-      // since these paths can get really long. To change how much of the path 
to see
-      // in diagnostics, one can update the maxParentDirectoriesForDiagnostics 
tunable
-      .takeRight(maxParentDirectoriesForDiagnostics + 1)
-    // we only want to use the prefix if the new number of directories is
-    // less than the original
-    val prefix = if (reducedTokens.length < tokens.length) s"...${splitter}" 
else ""
-    val newUriString = reducedTokens
-      .mkString(prefix, splitter, "")
-    newUriString
-  }
-
 }
 
 /**
diff --git 
a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/exceptions/SchemaFileLocatable.scala
 
b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/exceptions/SchemaFileLocatable.scala
index 1c01cbd85..1b0ec5334 100644
--- 
a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/exceptions/SchemaFileLocatable.scala
+++ 
b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/exceptions/SchemaFileLocatable.scala
@@ -17,9 +17,9 @@
 
 package org.apache.daffodil.lib.exceptions
 
-import java.net.URLDecoder
+import java.io.File
+import scala.xml.SAXParseException
 
-import org.apache.daffodil.lib.api.DaffodilTunables
 import org.apache.daffodil.lib.api.LocationInSchemaFile
 import org.apache.daffodil.lib.schema.annotation.props.LookupLocation
 
@@ -35,24 +35,24 @@ trait HasSchemaFileLocation extends LookupLocation {
 }
 
 object SchemaFileLocation {
-  def apply(context: SchemaFileLocatable, tunables: DaffodilTunables) =
+  def apply(context: SchemaFileLocatable) =
     new SchemaFileLocation(
       context.lineNumber,
       context.columnNumber,
       context.uriString,
+      context.diagnosticFile,
       context.toString,
       context.diagnosticDebugName,
-      tunables.maxParentDirectoriesForDiagnostics,
     )
 }
 
-class SchemaFileLocation private (
+class SchemaFileLocation protected (
   val lineNumber: Option[String],
   val columnNumber: Option[String],
   val uriString: String,
+  val diagnosticFile: File,
   contextToString: String,
   val diagnosticDebugName: String,
-  maxParentDirectoriesForDiagnostics: Int,
 ) extends LocationInSchemaFile
   with Serializable {
 
@@ -68,13 +68,7 @@ class SchemaFileLocation private (
 
   override val toString = contextToString
 
-  lazy val fileURITrimmed =
-    limitMaxParentDirectories(
-      URLDecoder.decode(uriString, "UTF-8"),
-      maxParentDirectoriesForDiagnostics,
-    )
-
-  override def fileDescription = " in " + fileURITrimmed
+  override def fileDescription = " in " + diagnosticFile
 
   override def locationDescription = {
     val showInfo = lineDescription != "" || fileDescription != ""
@@ -91,8 +85,6 @@ trait SchemaFileLocatable extends LocationInSchemaFile with 
HasSchemaFileLocatio
 
   def diagnosticDebugName: String
 
-  def tunables: DaffodilTunables
-
   lazy val lineNumber: Option[String] = lineAttribute match {
     case Some(seqNodes) => Some(seqNodes.toString)
     case None => None
@@ -113,12 +105,8 @@ trait SchemaFileLocatable extends LocationInSchemaFile 
with HasSchemaFileLocatio
     case None => ""
   }
 
-  lazy val fileURITrimmed = schemaFileLocation.fileURITrimmed
-
-  // URLDecoder removes %20, etc from the file name.
   override lazy val fileDescription = {
-    val newUriString: String = fileURITrimmed
-    " in " + newUriString
+    " in " + diagnosticFile
   }
 
   override lazy val locationDescription = {
@@ -147,6 +135,8 @@ trait SchemaFileLocatable extends LocationInSchemaFile with 
HasSchemaFileLocatio
    */
   def uriString: String
 
+  def diagnosticFile: File
+
   lazy val uriStringFromAttribute = {
     fileAttribute match {
       case Some(seqNodes) => Some(seqNodes.toString)
@@ -155,5 +145,36 @@ trait SchemaFileLocatable extends LocationInSchemaFile 
with HasSchemaFileLocatio
 
   }
 
-  override lazy val schemaFileLocation = SchemaFileLocation(this, tunables)
+  override lazy val schemaFileLocation = SchemaFileLocation(this)
+}
+
+class XercesSchemaFileLocation(
+  val xercesError: SAXParseException,
+  val schemaFileLocation: SchemaFileLocation,
+) extends SchemaFileLocation(
+    Option(xercesError.getLineNumber.toString),
+    Option(xercesError.getColumnNumber.toString),
+    xercesError.getSystemId,
+    schemaFileLocation.diagnosticFile,
+    schemaFileLocation.toString,
+    schemaFileLocation.diagnosticDebugName,
+  ) {
+  // we set this to blank string instead of "Schema File" since we don't have 
access to the element
+  // that causes this error from Xerces and "Schema File" doesn't really add 
much more info compared
+  // to the blank string
+  override val diagnosticDebugName = ""
+
+  // we have to override equals and hashCode because the OOlag error checks 
for duplicates in its error list
+  override def equals(obj: Any): Boolean = {
+    val xsflObj = obj.asInstanceOf[XercesSchemaFileLocation]
+    xsflObj.xercesError.getLineNumber == this.xercesError.getLineNumber &&
+    xsflObj.xercesError.getColumnNumber == this.xercesError.getColumnNumber &&
+    xsflObj.xercesError.getSystemId == this.xercesError.getSystemId &&
+    xsflObj.schemaFileLocation == this.schemaFileLocation
+  }
+
+  override def hashCode: Int = {
+    this.xercesError.hashCode() +
+      this.schemaFileLocation.hashCode()
+  }
 }
diff --git 
a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/Misc.scala 
b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/Misc.scala
index 70103e6f0..ff828f49a 100644
--- a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/Misc.scala
+++ b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/Misc.scala
@@ -708,4 +708,16 @@ object Misc {
     }
     Some(res)
   }
+
+  /**
+   * Get the diagnosticFilepath from a uri
+   */
+  def uriToDiagnosticFile(uri: URI): File = {
+    uri.getScheme match {
+      case "jar" => Paths.get(uri.toString.split("\\.jar!").last).toFile
+      case "file" => Paths.get(uri).toFile
+      case _ => Paths.get(uri.getPath).toFile
+    }
+  }
+
 }
diff --git 
a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/xml/DaffodilXMLLoader.scala
 
b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/xml/DaffodilXMLLoader.scala
index 8f33d2d41..c537fc0d9 100644
--- 
a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/xml/DaffodilXMLLoader.scala
+++ 
b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/xml/DaffodilXMLLoader.scala
@@ -27,6 +27,7 @@ import java.io.BufferedInputStream
 import java.io.InputStream
 import java.io.Reader
 import java.net.URI
+import java.nio.file.Paths
 import javax.xml.XMLConstants
 import javax.xml.parsers.SAXParserFactory
 import javax.xml.transform.Source
@@ -40,6 +41,7 @@ import scala.xml.SAXParser
 import scala.xml.parsing.NoBindingFactoryAdapter
 
 import org.apache.daffodil.lib.api.DaffodilSchemaSource
+import org.apache.daffodil.lib.api.URISchemaSource
 import org.apache.daffodil.lib.exceptions.Assert
 import org.apache.daffodil.lib.util.Logger
 import org.apache.daffodil.lib.util.Misc
@@ -244,12 +246,21 @@ class DFDLCatalogResolver private ()
         // comes from the schemaLocation attribute) on classpath or as a file.
         val optURI =
           try {
-            val contextURI = Some(new URI(baseURIString))
+            val baseURI = new URI(baseURIString)
+            // DaffodilXMLLoader implements a Xerces API, and Xerces doesn't 
have a concept of diagnostic path
+            // that we need for a URISchemaSource to pass in as the context 
for resolveSchemaLocation.
+            // We could use some heuristic to come up with a diagnostic path 
(e.g. call uriToDiagosticPath).
+            // But we don't actually use the diagnosticPath returned by 
resolveSchemaLocation here, all we care
+            // about is getting a URI for Xerces. So the diagnostic path in 
the schema source doesn't really
+            // matter as long as it doesn't break resolveSchemaLocation, and 
an empty diagnostic path works
+            // fine for that.
+            val uriSchemaSource = URISchemaSource(Paths.get("").toFile, 
baseURI)
+            val contextURI = Some(uriSchemaSource)
             val resolved = XMLUtils.resolveSchemaLocation(sysId, contextURI)
             // we drop the boolean return part of resolveSchemaLocation 
because we don't care here
             // if a relative schemaLocation was resolved absolutely. Daffodil 
will detect that
             // elsewhere and output a warning.
-            resolved.map(_._1)
+            resolved.map(_._1.uri)
           } catch {
             case e: IllegalArgumentException =>
               throw new SAXParseException(
diff --git 
a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/xml/XMLUtils.scala 
b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/xml/XMLUtils.scala
index 176bbda56..280d0e118 100644
--- a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/xml/XMLUtils.scala
+++ b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/xml/XMLUtils.scala
@@ -34,6 +34,8 @@ import scala.util.matching.Regex
 import scala.xml.NamespaceBinding
 import scala.xml._
 
+import org.apache.daffodil.lib.api.DaffodilSchemaSource
+import org.apache.daffodil.lib.api.URISchemaSource
 import org.apache.daffodil.lib.calendar.DFDLDateConversion
 import org.apache.daffodil.lib.calendar.DFDLDateTimeConversion
 import org.apache.daffodil.lib.calendar.DFDLTimeConversion
@@ -1423,8 +1425,8 @@ Differences were (path, expected, actual):
    */
   def resolveSchemaLocation(
     schemaLocation: String,
-    optContextURI: Option[URI],
-  ): Option[(URI, Boolean)] = {
+    optContextURI: Option[DaffodilSchemaSource],
+  ): Option[(URISchemaSource, Boolean)] = {
     val uri =
       try {
         new URI(schemaLocation)
@@ -1443,7 +1445,7 @@ Differences were (path, expected, actual):
         uri.getFragment == null &&
         uri.getPath != null
 
-    val optResolved: Option[(URI, Boolean)] =
+    val optResolved: Option[(URISchemaSource, Boolean)] =
       if (uri.isAbsolute) {
         // an absolute URI is one with a scheme. In this case, we expect to be 
able to resolve
         // the URI and do not try anything else (e.g. filesystem, classpath). 
Since this function
@@ -1452,7 +1454,8 @@ Differences were (path, expected, actual):
         // absolute URIs in includes/imports and cannot remove this yet.
         try {
           uri.toURL.openStream.close
-          Some(uri, false)
+          val uss = URISchemaSource(Misc.uriToDiagnosticFile(uri), uri)
+          Some(uss, false)
         } catch {
           case e: IOException => None
         }
@@ -1473,13 +1476,22 @@ Differences were (path, expected, actual):
             // absolute so we can use it as-is so getResource does not care 
what package this
             // class is in.
             val resource = this.getClass.getResource(uri.getPath)
-            if (resource != null) Some((resource.toURI, false)) else None
+            if (resource != null) {
+              val uss = URISchemaSource(new File(uri.getPath), resource.toURI)
+              Some((uss, false))
+            } else
+              None
           }
           .orElse {
             // Search for the schemaLocation path on the file system. This 
path is absolute so it
             // must exist. If it does not exist, this orElse block results in 
a None
             val file = Paths.get(uri.getPath).toFile
-            if (file.exists) Some((file.toURI, false)) else None
+            if (file.exists) {
+              val uss = URISchemaSource(file, file.toURI)
+              Some((uss, false))
+            } else {
+              None
+            }
           }
         optResolvedAbsolute
       } else {
@@ -1489,16 +1501,28 @@ Differences were (path, expected, actual):
         val optResolvedRelative = None
           .orElse {
             // This is a relative path, so look up the schemaLocation path 
relative to the context
-            Misc.getResourceRelativeOnlyOption(uri.getPath, contextURI).map { 
(_, false) }
+            val relativeURI =
+              Misc.getResourceRelativeOnlyOption(uri.getPath, 
contextURI.uriForLoading).map {
+                u =>
+                  val contextURIDiagnosticFile = contextURI.diagnosticFile
+                  val relativeDiagnosticFile =
+                    contextURIDiagnosticFile.toPath
+                      .resolveSibling(Paths.get(uri.getPath))
+                      .normalize()
+                      .toFile
+                  (URISchemaSource(relativeDiagnosticFile, u), false)
+              }
+            relativeURI
           }
           .orElse {
+            val uriPath = "/" + uri.getPath
             // The user might have meant an absolute schemaLocation but left 
off the leading
             // slash accidentally. Past versions of Daffodil allowed this, so 
we allow it too,
             // but return a boolean if a relative path was found absolutely so 
callers can warn
             // if needed. Future versions of Daffodil may want to remove this 
orElse block so we
             // are strict about how absolute vs relative schemaLocations are 
resolved.
-            val pair = Option(this.getClass.getResource("/" + uri.getPath))
-              .map { _.toURI }
+            val pair = Option(this.getClass.getResource(uriPath))
+              .map { r => URISchemaSource(new File(uriPath), r.toURI) }
               .map { (_, true) }
             pair
           }
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 7b1545be3..41912d473 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
@@ -379,19 +379,6 @@
             </xs:restriction>
           </xs:simpleType>
         </xs:element>
-        <xs:element name="maxParentDirectoriesForDiagnostics" default="3" 
minOccurs="0">
-          <xs:annotation>
-            <xs:documentation>
-              The maximum number of parent directories that show up for a file 
within a diagnostic
-              message.
-            </xs:documentation>
-          </xs:annotation>
-          <xs:simpleType>
-            <xs:restriction base="xs:int">
-              <xs:minInclusive value="0" />
-            </xs:restriction>
-          </xs:simpleType>
-        </xs:element>
         <xs:element name="maxSkipLengthInBytes" default="1024" minOccurs="0">
           <xs:annotation>
             <xs:documentation>
diff --git 
a/daffodil-propgen/src/main/scala/org/apache/daffodil/propGen/TunableGenerator.scala
 
b/daffodil-propgen/src/main/scala/org/apache/daffodil/propGen/TunableGenerator.scala
index a015ee724..8fcfaead5 100644
--- 
a/daffodil-propgen/src/main/scala/org/apache/daffodil/propGen/TunableGenerator.scala
+++ 
b/daffodil-propgen/src/main/scala/org/apache/daffodil/propGen/TunableGenerator.scala
@@ -50,6 +50,8 @@ class TunableGenerator(schemaRootConfig: scala.xml.Node, 
schemaRootExt: scala.xm
     |//
     
|////////////////////////////////////////////////////////////////////////////////////////////
     |
+    |import java.nio.file.Paths
+    |
     |import org.apache.daffodil.lib.exceptions.Assert
     |import org.apache.daffodil.lib.exceptions.ThrowsSDE
     |import 
org.apache.daffodil.lib.schema.annotation.props.EmptyElementParsePolicy
@@ -70,11 +72,12 @@ class TunableGenerator(schemaRootConfig: scala.xml.Node, 
schemaRootExt: scala.xm
     |
     |  def apply(): DaffodilTunables = {
     |    // override tunables from the global configuration file on the class 
path, if it exists
-    |    val (configOpt, _) = Misc.getResourceOption("/daffodil-config.xml")
+    |    val configPath = "/daffodil-config.xml"
+    |    val (configOpt, _) = Misc.getResourceOption(configPath)
     |    val configTunables: Map[String, String] =
     |      if (configOpt.isDefined) {
     |        val loader = new DaffodilXMLLoader()
-    |        val node = loader.load(URISchemaSource(configOpt.get), 
Some(XMLUtils.dafextURI))
+    |        val node = 
loader.load(URISchemaSource(Paths.get(configPath).toFile, configOpt.get), 
Some(XMLUtils.dafextURI))
     |        tunablesMap(node)
     |      } else {
     |        Map.empty
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/externalvars/ExternalVariablesLoader.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/externalvars/ExternalVariablesLoader.scala
index fc7e81be4..b5fd8fff7 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/externalvars/ExternalVariablesLoader.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/externalvars/ExternalVariablesLoader.scala
@@ -80,7 +80,10 @@ object ExternalVariablesLoader {
     val input = scala.io.Source.fromURI(file.toURI)(enc)
     val ldr = new DaffodilXMLLoader()
     val dafextURI = XMLUtils.dafextURI
-    val node = ldr.load(URISchemaSource(file.toURI), Some(dafextURI))
+    val node = ldr.load(
+      URISchemaSource(file, file.toURI),
+      Some(dafextURI),
+    )
     nodeToBindings(node)
   }
 
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/RuntimeData.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/RuntimeData.scala
index 76709e175..08135c1f1 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/RuntimeData.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/RuntimeData.scala
@@ -104,7 +104,7 @@ sealed trait RuntimeData
   final override def schemaFileLineColumnNumber: JLong =
     schemaFileLocation.columnNumber.map { JLong.getLong(_) }.orNull
 
-  final override def schemaFileInfo: String = schemaFileLocation.fileURITrimmed
+  final override def schemaFileInfo: String = 
schemaFileLocation.fileDescription
 }
 
 object TermRuntimeData {
diff --git 
a/daffodil-sapi/src/main/scala/org/apache/daffodil/sapi/Daffodil.scala 
b/daffodil-sapi/src/main/scala/org/apache/daffodil/sapi/Daffodil.scala
index 7eec0f333..50fff730f 100644
--- a/daffodil-sapi/src/main/scala/org/apache/daffodil/sapi/Daffodil.scala
+++ b/daffodil-sapi/src/main/scala/org/apache/daffodil/sapi/Daffodil.scala
@@ -33,6 +33,7 @@ import org.apache.daffodil.lib.api.{ DataLocation => 
SDataLocation }
 import org.apache.daffodil.lib.api.{ Diagnostic => SDiagnostic }
 import org.apache.daffodil.lib.api.{ LocationInSchemaFile => 
SLocationInSchemaFile }
 import org.apache.daffodil.lib.api.{ WithDiagnostics => SWithDiagnostics }
+import org.apache.daffodil.lib.util.Misc
 import org.apache.daffodil.lib.xml.DFDLCatalogResolver
 import org.apache.daffodil.lib.xml.XMLUtils
 import org.apache.daffodil.runtime1.api.DFDL.{
@@ -156,7 +157,7 @@ class Compiler private[sapi] (private var sCompiler: 
SCompiler) {
     optRootName: Option[String] = None,
     optRootNamespace: Option[String] = None,
   ): ProcessorFactory = {
-    val source = URISchemaSource(uri)
+    val source = URISchemaSource(Misc.uriToDiagnosticFile(uri), uri)
     val pf = sCompiler.compileSource(source, optRootName, optRootNamespace)
     new ProcessorFactory(pf.asInstanceOf[SProcessorFactory])
   }
diff --git 
a/daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/TDMLRunner.scala 
b/daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/TDMLRunner.scala
index 2c587913a..fd26368d4 100644
--- a/daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/TDMLRunner.scala
+++ b/daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/TDMLRunner.scala
@@ -68,6 +68,7 @@ import org.apache.daffodil.lib.util.MaybeInt
 import org.apache.daffodil.lib.util.Misc
 import org.apache.daffodil.lib.util.Misc.bits2Bytes
 import org.apache.daffodil.lib.util.Misc.hex2Bits
+import org.apache.daffodil.lib.util.Misc.uriToDiagnosticFile
 import org.apache.daffodil.lib.util.SchemaUtils
 import org.apache.daffodil.lib.xml.DaffodilXMLLoader
 import org.apache.daffodil.lib.xml.XMLUtils
@@ -320,14 +321,22 @@ class DFDLTestSuite private[tdml] (
       Logger.log.info(s"loading TDML file: ${tdmlFile}")
       val uri = tdmlFile.toURI()
       val newNode =
-        loader.load(URISchemaSource(uri), optTDMLSchema, addPositionAttributes 
= true)
+        loader.load(
+          URISchemaSource(tdmlFile, uri),
+          optTDMLSchema,
+          addPositionAttributes = true,
+        )
       val res = (newNode, uri)
       Logger.log.debug(s"done loading TDML file: ${tdmlFile}")
       res
     }
     case uri: URI => {
       val newNode =
-        loader.load(URISchemaSource(uri), optTDMLSchema, addPositionAttributes 
= true)
+        loader.load(
+          URISchemaSource(Misc.uriToDiagnosticFile(uri), uri),
+          optTDMLSchema,
+          addPositionAttributes = true,
+        )
       val res = (newNode, uri)
       res
     }
@@ -707,12 +716,6 @@ abstract class TestCase(testCaseXML: NodeSeq, val parent: 
DFDLTestSuite) {
       }
     case other => Assert.invariantFailed("unrecognized validation enum string: 
" + other)
   }
-  lazy val avoidFalsePositiveMatchesWithLocationInfo =
-    (testCaseXML \ "@diagnosticsStripLocationInfo").text match {
-      case "true" => true
-      case "false" => false
-      case _ => true
-    }
 
   lazy val shouldValidate = validationMode != ValidationMode.Off
   lazy val expectsValidationError =
@@ -758,7 +761,7 @@ abstract class TestCase(testCaseXML: NodeSeq, val parent: 
DFDLTestSuite) {
       case (None, Some(uri)) => {
         //
         // In this case, we have a real TDML file (or resource) to open
-        URISchemaSource(uri)
+        URISchemaSource(Misc.uriToDiagnosticFile(uri), uri)
       }
     } // end match
     suppliedSchema
@@ -774,7 +777,10 @@ abstract class TestCase(testCaseXML: NodeSeq, val parent: 
DFDLTestSuite) {
       case (name, Some(x), None) if name != "" => Some(x)
       case (name, None, Some(uri)) if name != "" => {
         // Read file, convert to definedConfig
-        val node = parent.loader.load(URISchemaSource(uri), 
Some(XMLUtils.dafextURI))
+        val node = parent.loader.load(
+          URISchemaSource(uriToDiagnosticFile(uri), uri),
+          Some(XMLUtils.dafextURI),
+        )
         if (node eq null)
           throw TDMLException(parent.loadingExceptions.toSeq, None)
         val definedConfig = DefinedConfig(node, parent)
@@ -950,7 +956,6 @@ abstract class TestCase(testCaseXML: NodeSeq, val parent: 
DFDLTestSuite) {
         diagnostics,
         Some(errors),
         implString,
-        avoidFalsePositiveMatchesWithLocationInfo,
       )
 
     if (
@@ -961,7 +966,6 @@ abstract class TestCase(testCaseXML: NodeSeq, val parent: 
DFDLTestSuite) {
         diagnostics,
         optWarnings,
         implString,
-        avoidFalsePositiveMatchesWithLocationInfo,
       )
   }
 }
@@ -1179,7 +1183,6 @@ case class ParserTestCase(ptc: NodeSeq, parentArg: 
DFDLTestSuite)
           actual.getDiagnostics,
           optExpectedValidationErrors,
           implString,
-          avoidFalsePositiveMatchesWithLocationInfo,
         ) // verify all validation errors were found
         Assert.invariant(actual.isValidationError)
       }
@@ -1202,7 +1205,6 @@ case class ParserTestCase(ptc: NodeSeq, parentArg: 
DFDLTestSuite)
         allDiags,
         optExpectedWarnings,
         implString,
-        avoidFalsePositiveMatchesWithLocationInfo,
       )
   }
 
@@ -1568,7 +1570,6 @@ case class UnparserTestCase(ptc: NodeSeq, parentArg: 
DFDLTestSuite)
         allDiags,
         optWarnings,
         implString,
-        avoidFalsePositiveMatchesWithLocationInfo,
       )
 
     if (roundTrip eq OnePassRoundTrip) {
@@ -1613,7 +1614,6 @@ case class UnparserTestCase(ptc: NodeSeq, parentArg: 
DFDLTestSuite)
           actual.getDiagnostics,
           optWarnings,
           implString,
-          avoidFalsePositiveMatchesWithLocationInfo,
         )
 
       (shouldValidate, expectsValidationError) match {
@@ -1625,7 +1625,6 @@ case class UnparserTestCase(ptc: NodeSeq, parentArg: 
DFDLTestSuite)
             actual.getDiagnostics,
             optExpectedValidationErrors,
             implString,
-            avoidFalsePositiveMatchesWithLocationInfo,
           ) // verify all validation errors were found
           Assert.invariant(actual.isValidationError)
         }
@@ -1781,21 +1780,11 @@ object VerifyTestCase {
    * @param actualDiags                               Actual diagnostics 
produced
    * @param expectedDiags                             Expected diagnostics 
from test cases
    * @param implString                                Implementation string
-   * @param avoidFalsePositiveMatchesWithLocationInfo We strip the file info 
from the diagnostics to prevent false
-   *                                                  positive matches against 
the test case's error and warning strings
-   *                                                  coming from file/dir 
names.
-   *                                                  As there are tests that 
look for correct file/dir names, those
-   *                                                  tests will need to NOT 
strip them and can do so by setting the
-   *                                                  test flag to false.
-   *                                                  This is only for 
purposes of comparing error/warning strings
-   *                                                  to the diagnostic 
messages. Users would always see, displayed,
-   *                                                  the full diagnostic 
messages.
    */
   def verifyAllDiagnosticsFound(
     actualDiags: Seq[Diagnostic],
     expectedDiags: Option[ErrorWarningBase],
     implString: Option[String],
-    avoidFalsePositiveMatchesWithLocationInfo: Boolean = true,
   ) = {
 
     val actualDiagMsgs = actualDiags.map {
@@ -1826,11 +1815,7 @@ object VerifyTestCase {
         expectedDiag.messages.foreach { expectedMsg =>
           {
             val wasFound = actualDiags.exists { actualDiag =>
-              val actualDiagMsg = if 
(avoidFalsePositiveMatchesWithLocationInfo) {
-                stripLocationInformation(actualDiag.getMessage())
-              } else {
-                actualDiag.getMessage()
-              }
+              val actualDiagMsg = actualDiag.getMessage()
               actualDiag.isError == expectedDiag.isError &&
               actualDiagMsg.toLowerCase.contains(expectedMsg.toLowerCase)
             }
@@ -2723,7 +2708,7 @@ case class DFDLInfoset(di: Node, parent: Infoset) {
               "TDMLRunner: infoset file '" + path + "' was not found",
             ),
           )
-          URISchemaSource(uri)
+          URISchemaSource(uriToDiagnosticFile(uri), uri)
         }
         case value => Assert.abort("Unknown value for type attribute on 
dfdlInfoset: " + value)
       }
diff --git 
a/daffodil-test/src/test/resources/org/apache/daffodil/section00/general/TestResolver.tdml
 
b/daffodil-test/src/test/resources/org/apache/daffodil/section00/general/TestResolver.tdml
index 4ebc6c286..6d5eddc85 100644
--- 
a/daffodil-test/src/test/resources/org/apache/daffodil/section00/general/TestResolver.tdml
+++ 
b/daffodil-test/src/test/resources/org/apache/daffodil/section00/general/TestResolver.tdml
@@ -36,7 +36,6 @@
     <tdml:document/>
     <tdml:errors>
       <tdml:error>Schema Definition Error</tdml:error>
-      <tdml:error>SAXParseException</tdml:error>
       <tdml:error>Unable to resolve</tdml:error>
       <tdml:error>this/does/not/exist/schema.dfdl.xsd</tdml:error>
     </tdml:errors>
diff --git 
a/daffodil-test/src/test/resources/org/apache/daffodil/section00/general/disallowDocTypes.tdml
 
b/daffodil-test/src/test/resources/org/apache/daffodil/section00/general/disallowDocTypes.tdml
index 77f784ba5..2478bc0bb 100644
--- 
a/daffodil-test/src/test/resources/org/apache/daffodil/section00/general/disallowDocTypes.tdml
+++ 
b/daffodil-test/src/test/resources/org/apache/daffodil/section00/general/disallowDocTypes.tdml
@@ -59,8 +59,6 @@
     <tdml:document/>
     <tdml:errors>
       <tdml:error>Schema Definition Error</tdml:error>
-      <tdml:error>org.xml.sax.SAXParseException</tdml:error>
-      <tdml:error>hasDocType-include.dfdl.xsd</tdml:error>
       <tdml:error>DOCTYPE is disallowed</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
@@ -70,8 +68,6 @@
     <tdml:document/>
     <tdml:errors>
       <tdml:error>Schema Definition Error</tdml:error>
-      <tdml:error>org.xml.sax.SAXParseException</tdml:error>
-      <tdml:error>hasDocType-import.dfdl.xsd</tdml:error>
       <tdml:error>DOCTYPE is disallowed</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
diff --git 
a/daffodil-test/src/test/resources/org/apache/daffodil/section02/schema_definition_errors/SchemaDefinitionErrors.tdml
 
b/daffodil-test/src/test/resources/org/apache/daffodil/section02/schema_definition_errors/SchemaDefinitionErrors.tdml
index 7e022d64c..045b98685 100644
--- 
a/daffodil-test/src/test/resources/org/apache/daffodil/section02/schema_definition_errors/SchemaDefinitionErrors.tdml
+++ 
b/daffodil-test/src/test/resources/org/apache/daffodil/section02/schema_definition_errors/SchemaDefinitionErrors.tdml
@@ -224,8 +224,7 @@
 
   <tdml:parserTestCase name="schema_line_number" root="e1"
                        model="lineNumber.dfdl.xsd"
-                       description=""
-                       diagnosticsStripLocationInfo="false">
+                       description="">
     <tdml:document />
 
     <tdml:errors>
@@ -237,68 +236,6 @@
 
   </tdml:parserTestCase>
 
-  <tdml:parserTestCase name="schema_file_path" root="e1"
-                       model="lineNumber.dfdl.xsd"
-                       description=""
-                       diagnosticsStripLocationInfo="false">
-    <tdml:document />
-
-    <tdml:errors>
-      <tdml:error>Schema Definition Error</tdml:error>
-      
<tdml:error>.../daffodil/section02/schema_definition_errors/lineNumber.dfdl.xsd</tdml:error>
-      <tdml:error>line 65</tdml:error>
-      <tdml:error>column 10</tdml:error>
-    </tdml:errors>
-
-  </tdml:parserTestCase>
-
-  <tdml:defineConfig name="cfg_maxParentDirectoriesForDiagnostics_1">
-    <daf:tunables xmlns="http://www.w3.org/2001/XMLSchema";
-                  xmlns:xs="http://www.w3.org/2001/XMLSchema";>
-      
<daf:maxParentDirectoriesForDiagnostics>2</daf:maxParentDirectoriesForDiagnostics>
-    </daf:tunables>
-  </tdml:defineConfig>
-
-  <tdml:parserTestCase name="schema_file_path_tunable_1" root="e1"
-                       model="lineNumber.dfdl.xsd"
-                       description=""
-                       config="cfg_maxParentDirectoriesForDiagnostics_1"
-                       diagnosticsStripLocationInfo="false">
-    <tdml:document />
-
-    <tdml:errors>
-      <tdml:error>Schema Definition Error</tdml:error>
-      
<tdml:error>.../section02/schema_definition_errors/lineNumber.dfdl.xsd</tdml:error>
-      <tdml:error>line 65</tdml:error>
-      <tdml:error>column 10</tdml:error>
-    </tdml:errors>
-
-  </tdml:parserTestCase>
-
-  <tdml:defineConfig name="cfg_maxParentDirectoriesForDiagnostics_2">
-    <daf:tunables xmlns="http://www.w3.org/2001/XMLSchema";
-                  xmlns:xs="http://www.w3.org/2001/XMLSchema";>
-      
<daf:maxParentDirectoriesForDiagnostics>0</daf:maxParentDirectoriesForDiagnostics>
-    </daf:tunables>
-  </tdml:defineConfig>
-
-  <tdml:parserTestCase name="schema_file_path_tunable_2" root="e1"
-                       model="lineNumber.dfdl.xsd"
-                       description=""
-                       config="cfg_maxParentDirectoriesForDiagnostics_2"
-                       diagnosticsStripLocationInfo="false">
-    <tdml:document />
-
-    <tdml:errors>
-      <tdml:error>Schema Definition Error</tdml:error>
-      <tdml:error>.../lineNumber.dfdl.xsd</tdml:error>
-      <tdml:error>line 65</tdml:error>
-      <tdml:error>column 10</tdml:error>
-    </tdml:errors>
-
-  </tdml:parserTestCase>
-
-
   <!--
       Test Name: missing_closing_tag
          Schema: MissingClosingTag.dfdl.xsd
diff --git 
a/daffodil-test/src/test/resources/org/apache/daffodil/section06/namespaces/namespaces.tdml
 
b/daffodil-test/src/test/resources/org/apache/daffodil/section06/namespaces/namespaces.tdml
index fd2663b3f..7493a97f4 100644
--- 
a/daffodil-test/src/test/resources/org/apache/daffodil/section06/namespaces/namespaces.tdml
+++ 
b/daffodil-test/src/test/resources/org/apache/daffodil/section06/namespaces/namespaces.tdml
@@ -715,8 +715,7 @@
 
   <tdml:parserTestCase name="long_chain_05" root="rabbitHole5"
                        model="multi_base_03.dfdl.xsd"
-                       description="import a schema - DFDL-6-007R"
-                       diagnosticsStripLocationInfo="false">
+                       description="import a schema - DFDL-6-007R">
     <tdml:document><![CDATA[5632]]></tdml:document>
     <tdml:errors>
       <tdml:error>Schema Definition Error</tdml:error>
@@ -1010,8 +1009,7 @@
         the
         error messages to specifically mention this file, not just show that
         it was included. -->
-      <tdml:error>file:</tdml:error>
-      <tdml:error>subfolder/multi_C_06_nons.dfdl.xsd</tdml:error>
+      <tdml:error>multi_C_06_nons.dfdl.xsd</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -2144,8 +2142,7 @@
   -->
   <tdml:parserTestCase name="junkAnnotation01" root="x"
                        model="junk-annotation-01.dfdl.xsd"
-                       description="Diagnostic provides proper line number and 
file when a junk annotation is found - DFDL-6-007R"
-                       diagnosticsStripLocationInfo="false">
+                       description="Diagnostic provides proper line number and 
file when a junk annotation is found - DFDL-6-007R">
     <tdml:document />
     <tdml:errors>
       <tdml:error>Schema Definition Error</tdml:error>
@@ -2211,12 +2208,11 @@
 
   <tdml:parserTestCase name="errorLocations_01" root="rabbitHole"
                        model="multi_base_13.dfdl.xsd"
-                       description="import a schema - DFDL-6-007R"
-                       diagnosticsStripLocationInfo="false">
+                       description="import a schema - DFDL-6-007R">
     <tdml:document><![CDATA[temp]]></tdml:document>
       <tdml:errors>
         <tdml:error>nonExistent</tdml:error>
-        <tdml:error>namespaces/multi_C_13.dfdl.xsd</tdml:error>
+        <tdml:error>multi_C_13.dfdl.xsd</tdml:error>
       </tdml:errors>
   </tdml:parserTestCase>
   
diff --git 
a/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_expressions/expression_fail.tdml
 
b/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_expressions/expression_fail.tdml
index 654926037..d594cddbc 100644
--- 
a/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_expressions/expression_fail.tdml
+++ 
b/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_expressions/expression_fail.tdml
@@ -67,7 +67,6 @@
        <tdml:error>Error</tdml:error>
        <tdml:error>loading</tdml:error>
        <tdml:error>schema</tdml:error>
-       <tdml:error>SAXParseException</tdml:error>
        <tdml:error>not</tdml:error>
        <tdml:error>facet-valid</tdml:error>
        <tdml:error>dfdl:occursCount</tdml:error>
diff --git 
a/daffodil-test/src/test/scala/org/apache/daffodil/infoset/TestStringAsXml.scala
 
b/daffodil-test/src/test/scala/org/apache/daffodil/infoset/TestStringAsXml.scala
index b57f4ab4b..d07de5d8e 100644
--- 
a/daffodil-test/src/test/scala/org/apache/daffodil/infoset/TestStringAsXml.scala
+++ 
b/daffodil-test/src/test/scala/org/apache/daffodil/infoset/TestStringAsXml.scala
@@ -44,7 +44,9 @@ class TestStringAsXml {
 
   private def compileSchema(dfdlSchemaURI: URI) = {
     val c = Compiler()
-    val pf = c.compileSource(URISchemaSource(dfdlSchemaURI))
+    val pf = c.compileSource(
+      URISchemaSource(Misc.uriToDiagnosticFile(dfdlSchemaURI), dfdlSchemaURI),
+    )
     val dp = pf.onPath("/")
     dp.withValidationMode(ValidationMode.Full)
   }
diff --git 
a/daffodil-test/src/test/scala/org/apache/daffodil/section02/schema_definition_errors/TestSDE.scala
 
b/daffodil-test/src/test/scala/org/apache/daffodil/section02/schema_definition_errors/TestSDE.scala
index b9e32d977..4aaa08f89 100644
--- 
a/daffodil-test/src/test/scala/org/apache/daffodil/section02/schema_definition_errors/TestSDE.scala
+++ 
b/daffodil-test/src/test/scala/org/apache/daffodil/section02/schema_definition_errors/TestSDE.scala
@@ -42,14 +42,6 @@ class TestSDE {
   @Test def test_schema_component_err(): Unit = { 
runner.runOneTest("schema_component_err") }
 
   @Test def test_schema_line_number(): Unit = { 
runner.runOneTest("schema_line_number") }
-  @Test def test_schema_file_path(): Unit = { 
runner.runOneTest("schema_file_path") }
-  @Test def test_schema_file_path_tunable_1(): Unit = {
-    runner.runOneTest("schema_file_path_tunable_1")
-  }
-  @Test def test_schema_file_path_tunable_2(): Unit = {
-    runner.runOneTest("schema_file_path_tunable_2")
-  }
-
   @Test def test_schema_warning(): Unit = { 
runner.runOneTest("schema_warning") }
   @Test def test_missing_appinfo_source(): Unit = {
     runner.runOneTest("missing_appinfo_source")

Reply via email to