BATMAN_2008
BATMAN_2008

Reputation: 3530

Java SaxParser Schema Validation: results in SAXParseException; lineNumber: 46; Cannot resolve the name

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;
  }
}

Upvotes: 0

Views: 297

Answers (1)

Michael Kay
Michael Kay

Reputation: 163587

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.

Upvotes: 0

Related Questions