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 e5851a76c Fix Resolve Schema Location for xsi:SchemaLocation in Config
files
e5851a76c is described below
commit e5851a76ccb03e76285d4f25db55125b3b37bf0b
Author: olabusayoT <[email protected]>
AuthorDate: Wed Oct 9 22:15:09 2024 -0400
Fix Resolve Schema Location for xsi:SchemaLocation in Config files
- currently, due to a bug in Xerces xsi:schemaLocation URIs are
absolutized, which causes resolveCommon to not set the resolvedUri to the path
it resolves from namespace, since the absolute URI doesn't match the end of the
resolvedURI. This fix converts systemId to a URI and uses its path when
comparing with resolvedURI, therefore resulting in a successful resolution.
- add comment explaining systemIdPath check change
- add schema location to config to prove it doesn't cause failure
DAFFODIL-2339
---
.../daffodil/lib/xml/DaffodilXMLLoader.scala | 34 ++++++++++++++++++++--
.../daffodil_config_cli_test.xml | 24 +++------------
2 files changed, 36 insertions(+), 22 deletions(-)
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 68f7645f8..34eb2fda5 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
@@ -216,12 +216,41 @@ class DFDLCatalogResolver private ()
// because the nsURI will resolve to the including schema file.
// This will cause the including schema to be repeatedly parsed resulting
in a stack overflow.
+ lazy val systemIdUri = if (systemId != null) {
+ new URI(systemId)
+ } else {
+ null
+ }
+
+ /**
+ * Xerces has a bug where it absolutizes systemId i.e the user supplies
+ * {{{
+ * <xs:schema...
+ * ... xsi:schemaLocation="urn:some:namespace /some/path.xsd"
+ * }}}
+ * Xerces takes that schemaLocation URI and absolutizes it to {{{
file:/some/path.xsd }}}
+ * and passes that to our resolveEntity and in turn resolveCommon, which
while it's able
+ * to find the namespace, fails to set the resolvedUri since the
file:/some/path.xsd will
+ * never match anything resolved from our catalog since that'd return
something like
+ * {{{ file:/some/absolute/path/to/some/path.xsd }}}
+ *
+ * This is a workaround to that bug where we convert systemId to a URI and
check if the
+ * path (from URI.getPath) matches the end of resolvedUri. Note: This can
ignore absolute
+ * URIs passed in for schemaLocation, but those are edge cases where the
user expects
+ * the namespace to match a different file (i.e what they provide in the
schemalocation)
+ * than what we find in the catalog.
+ */
+ lazy val systemIdPath = if (systemIdUri != null && systemIdUri.getScheme
== "file") {
+ systemIdUri.getPath
+ } else {
+ systemId
+ }
val resolvedId = {
if (resolvedSystem != null && resolvedSystem != resolvedUri) {
resolvedSystem
} else if (
resolvedUri != null && ((systemId == null) || (systemId != null &&
resolvedUri.endsWith(
- systemId
+ systemIdPath
)))
) {
resolvedUri
@@ -698,7 +727,8 @@ class DaffodilXMLLoader(val errorHandler:
org.xml.sax.ErrorHandler)
// We must use XMLReader setProperty() function to set the entity
resolver--calling
// setEntityResolver with the Xerces XML reader causes validation to
fail for some
- // reason. We call the right function below, but unfortunately,
scala-xml calls
+ // reason (we get a "cvc-elt.1.a: Cannot find the declaration of
element 'schema'" error).
+ // We call the right function below, but unfortunately, scala-xml calls
// setEntityResolver in loadDocument(), which cannot be disabled and
scala-xml does not
// want to change. To avoid this, we wrap the Xerces XMLReader in an
XMLFilterImpl and
// override setEntityResolver to a no-op. However, XMLFilterImpl
parse() calls
diff --git
a/daffodil-test/src/test/resources/org/apache/daffodil/section07/external_variables/daffodil_config_cli_test.xml
b/daffodil-test/src/test/resources/org/apache/daffodil/section07/external_variables/daffodil_config_cli_test.xml
index f714d0e65..262111c28 100644
---
a/daffodil-test/src/test/resources/org/apache/daffodil/section07/external_variables/daffodil_config_cli_test.xml
+++
b/daffodil-test/src/test/resources/org/apache/daffodil/section07/external_variables/daffodil_config_cli_test.xml
@@ -15,26 +15,10 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
-<!--
- Note: Bug DAFFODIL-2339
-
- We'd like to have these schemaLocation attributes on daf:dfdlConfig, but
this breaks tests because
- it tries to load the schema from the schemaLocation, and can't resolve
org/apache/daffodil/xsd/dafext.xsd.
-
- Simple things like adding an sbt dependency from daffodil-cli back to
daffodil-lib, whether always or "it->test"
- dependent, don't fix this.
-
- The CLI is using DaffodilXMLLoader to load this config file, so the resolver
should be doing the right thing by
- finding this dafext.xsd on the class path inside of daffodil-lib's jar.
-
- The failure seems to happen earlier. A SAX fatal error is invoked when
looking up dfdl:anyOther a symbol
- in the dfdl schema annotation schemas, from the XMLSchema_for_DFDL.
-
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="urn:ogf:dfdl:2013:imp:daffodil.apache.org:2018:ext
org/apache/daffodil/xsd/dafext.xsd"
--->
-<daf:dfdlConfig xmlns:daf="urn:ogf:dfdl:2013:imp:daffodil.apache.org:2018:ext">
+<daf:dfdlConfig xmlns:daf="urn:ogf:dfdl:2013:imp:daffodil.apache.org:2018:ext"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
xsi:schemaLocation="urn:ogf:dfdl:2013:imp:daffodil.apache.org:2018:ext
/org/apache/daffodil/xsd/dafext.xsd"
+>
<daf:externalVariableBindings xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:ex="http://example.com">
<daf:bind name="ex:var1">-9</daf:bind>