0

I have an XSD that internally calls many other XSD files. I have added all the relevant files to my src/main/java/resources folder. Now I am trying to read these schema files by calling the rootSchema and trying to validate them against the incoming XML file.

I am using the SaxParser validation schema to do the validation, but for some reason when I am trying to read the schema file it results in the error:

org.xml.sax.SAXParseException; lineNumber: 27; columnNumber: 48; src-resolve: Cannot resolve the name 'global:Document' to a(n) 'type definition' component.

My rootschema file has the following content on line 27:

<xsd:extension base="global:Document">

The rootSchema file has the inclusion of this file at the top xsd tag something like this:

<xsd:schema xmlns:global="urn:global:xsd:1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:global:company:xsd:2" elementFormDefault="unqualified" attributeFormDefault="unqualified" version="2.0">

Also, my rootSchema is importing the global.xsd something like this on line 16:

<xsd:import namespace="urn:global:xsd:1" schemaLocation="./global.xsd"/>

Also the file global.xsd is present within my resources folder and able to navigate to the file directly by clicking on Intellij shortcut cmd+mouse click. Even after everything, I am not sure why SaxParser is unable to find the file.

My global.xsd looks something like this:

<xsd:schema xmlns:global="urn:global:xsd:1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:global:xsd:1" elementFormDefault="unqualified" attributeFormDefault="unqualified" version="1.0">
    <xsd:annotation>
        <xsd:documentation>
            <global:copyright>Copyright (C) 2004 global Inc., All Rights Reserved.</global:copyright>
            <global:specification>global common components Version 1.0</global:specification>
        </xsd:documentation>
    </xsd:annotation>
    <xsd:complexType name="Document" abstract="true">
        <xsd:annotation>
            <xsd:documentation xml:lang="en">
                global document properties for all messages.
            </xsd:documentation>
        </xsd:annotation>
        <xsd:attribute name="schemaVersion" type="xsd:decimal" use="required">
            <xsd:annotation>
                <xsd:documentation xml:lang="en">
                    The version of the schema corresponding to which the instance conforms. 
                </xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="creationDate" type="xsd:dateTime" use="required">
            <xsd:annotation>
                <xsd:documentation xml:lang="en">
                    The date the message was created. Used for auditing and logging.
                </xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
    </xsd:complexType>
</xsd:schema>

I saw many questions related to the same and tried a few of them, but still, it's not working. I also saw a few suggestions to merge all XSD files into one, but this is not possible for me as there are many other dependent XSD files and merging would be difficult. Can someone please suggest some workarounds?

Following is the code that I trying:

import java.io.InputStream;
import javax.xml.XMLConstants;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

public class XmlSchemaValidator {

  private final SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
  private final Schema xmlCaptureSchema;

  private static final String[] XSD_FILES = {
    "/Types.xsd", 
    "/Identification.xsd",
    "/Partner.xsd",
    "/Manifest.xsd", 
    "/BusinessScope.xsd",
    "/BusinessDocumentHeader.xsd", 
    "/global.xsd",
    "/global-1_1.xsd",
    "/global-query-1_1.xsd",
    "/global-masterdata-1_1.xsd",
  };

  public XmlSchemaValidator() {
    //this.xmlCaptureSchema = loadSchema("/global-1_1.xsd");
    this.xmlCaptureSchema = loadSchemaType2();
  }

  public void validateAgainstCaptureSchema(final InputStream input) {
    try {
      final Validator validator = xmlCaptureSchema.newValidator();
      validator.validate(new StreamSource(input));
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public Schema loadSchema(final String name) {
    Schema schema = null;
    try {
      schema = schemaFactory.newSchema(new StreamSource(getClass().getResourceAsStream(name)));
    } catch (Exception e) {
      e.printStackTrace();
    }
    return schema;
  }

  public Schema loadSchemaType2() {
    Schema schema = null;
    try {
      Source[] xsdSources = new Source[XSD_FILES.length];
      int i = 0;

      for (String xsdFile : XSD_FILES) {
        final InputStream xsdStreamData = getClass().getResourceAsStream(xsdFile);
        final StreamSource xsdStreamSource = new StreamSource(xsdStreamData);
        xsdSources[i] = xsdStreamSource;
        i++;
      }
      schema = schemaFactory.newSchema(xsdSources);
    } catch (Exception e) {
      e.printStackTrace();
    }
    return schema;
  }
}
3
  • You have not provided any evidence that you are importing global.xsd in your root schema. The snippet that you posted shows the declaration of the namespace prefix 'global' but that will not cause global.xsd to be imported into the schema. You need an <xsd:import> tag to do that. Commented Dec 7, 2022 at 11:58
  • @kimbert Thanks a lot for the response, I missed out on that part sorry for that. I have modified the question with the information about import. Please have a look. I also tried to import all the files as mentioned in one of the other questions but that also not working. I have modified my code as well. Please suggest something. Commented Dec 7, 2022 at 12:20
  • After a lot of trying and searching I was able to figure it out. The thing is that SaxParser expects the absolute path and relative path won't work. When I changed the import path to something like this then it worked for me: schemaLocation="./global.xsd" to schemaLocation = "/Users/name/projects/validation/src/main/resources/xsd/global.xsd" Commented Dec 12, 2022 at 13:19

1 Answer 1

0
Even after everything, I am not sure why SaxParser is unable to find the file.

It didn't say it couldn't find the file. It said:

Cannot resolve the name 'global:Document' to a(n) 'type definition' component.

That sounds to me like it read the imported file and couldn't find the type definition within the file. You haven't shown is the imported file, so we can't investigate that.

Sign up to request clarification or add additional context in comments.

7 Comments

Sorry, maybe I missed adding. I have added it now for your reference. Can you please have a look and provide some suggestions?
Thanks for the extra information. I can't see anything obviously wrong in what you've shown us (which is either because I'm missing something, or because the error is in something you haven't shown us). Sorry I can't be of more help.
Do I need to provide only the root XSD file and SaxParser will automatically call others depending XSD file or do I need to provide all the files?
Try to provide a minimal but complete reproducible example: all the files needed for someone else to replicate the problem, packaged in a way that they can easily install, and cutting out everything that doesn't contribute anything to an understanding of the problem.
After a lot of trying and searching I was able to figure it out. The thing is that SaxParser expects the absolute path and relative path won't work. When I changed the import path to something like this then it worked for me: schemaLocation="./global.xsd" to schemaLocation = "/Users/name/projects/validation/src/main/resources/xsd/global.xsd"
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.