Search code examples
javaxmlxsdxml-validation

Validating xml against xsd file generated through JAXB and XSD build option in eclipse


I am trying to have a sample code for validating my xml file against xsd file, which is getting generated through jaxb and xsd build through Eclipse.

I am trying to do a sample validator file, that validates my xml against my xsd file. Now, I have found a lot of examples for the java code, and I am using one of them. Also I have recieved a lot of answers for the issue that I am facing, but some way the answers suggests to either update my xsd or xml file. For me, I cannot do any of these, as I am generating the xsd files through jaxb and xsd build option through Eclipse.

try {
SchemaFactory factory = 
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = factory.newSchema(new File(xsdPath));
Validator validator = schema.newValidator();
validator.validate(new StreamSource(new File(xmlPath)));
} catch (IOException e) {
System.out.println("Exception: "+e.getMessage());
return false;
} catch( SAXException e){
System.out.println("Exception: "+e.getMessage());
return false;
}
return true;
}

My XML File
<!DOCTYPE MLIspec SYSTEM "MLIspec-1.6.dtd"> 
<MLIspec> 
<id>4050response</id> 
<typename>4050Response</typename> 
<description>Show the Contract Numbers</description>    
<element> 
<id>7504</id> 
<name>SourceAccountIdentifier</name> 
<type>table</type> 
<required>true</required>       
</element>
</MLIspec>
XSD file

<?xml version="1.0" encoding="UTF-8"?><xs:schema xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:cdcla="cdcla" jxb:version="1.0">
<xs:include schemaLocation="SourceAccountIdentifier.xsd"/>
<xs:complexType name="MXMLI4050Response">
<xs:annotation>
<xs:appinfo>
<jxb:class name="MXMLI4050Response">
<jxb:javadoc>4050response - MXMLI4050Response. Show the Contract Numbers. </jxb:javadoc>
</jxb:class>
<cdcla:elf group="true"/>
</xs:appinfo>
</xs:annotation>
<xs:all>
<xs:element name="e7920" type="xs:integer" minOccurs="0">
<xs:annotation>
<xs:documentation>MessageFunctionCode</xs:documentation>
<xs:appinfo>
<jxb:property name="MessageFunctionCode">
<jxb:javadoc>7920 - MessageFunctionCode. </jxb:javadoc>
<jxb:baseType>
<jxb:javaType name="java.lang.Integer" parseMethod="com.citigroup.cdcla.gmli.bind.DatatypeConverter.parseIntegerFromDatatypeN" printMethod="com.citigroup.cdcla.gmli.bind.DatatypeConverter.printIntegerAsDatatypeN"/>
</jxb:baseType>
</jxb:property>
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="e8002" type="xs:integer" minOccurs="0">
<xs:annotation>
<xs:documentation>TerminalID</xs:documentation>
<xs:appinfo>
<jxb:property name="TerminalID">
<jxb:javadoc>8002 - TerminalID. </jxb:javadoc>
<jxb:baseType>
<jxb:javaType name="java.lang.Integer" parseMethod="com.citigroup.cdcla.gmli.bind.DatatypeConverter.parseIntegerFromDatatypeN" printMethod="com.citigroup.cdcla.gmli.bind.DatatypeConverter.printIntegerAsDatatypeN"/>
</jxb:baseType>
</jxb:property>
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="e8005" type="xs:integer" minOccurs="0">
<xs:annotation>
<xs:documentation>MessageSequenceNumber</xs:documentation>
<xs:appinfo>
<jxb:property name="MessageSequenceNumber">
<jxb:javadoc>8005 - MessageSequenceNumber. </jxb:javadoc>
<jxb:baseType>
<jxb:javaType name="java.lang.Integer" parseMethod="com.citigroup.cdcla.gmli.bind.DatatypeConverter.parseIntegerFromDatatypeN" printMethod="com.citigroup.cdcla.gmli.bind.DatatypeConverter.printIntegerAsDatatypeN"/>
</jxb:baseType>
</jxb:property>
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="e7300" type="xs:integer" minOccurs="0">
<xs:annotation>
<xs:documentation>AcquirerResponseCode</xs:documentation>
<xs:appinfo>
<jxb:property name="AcquirerResponseCode">
<jxb:javadoc>7300 - AcquirerResponseCode. </jxb:javadoc>
<jxb:baseType>
<jxb:javaType name="java.lang.Integer" parseMethod="com.citigroup.cdcla.gmli.bind.DatatypeConverter.parseIntegerFromDatatypeN" printMethod="com.citigroup.cdcla.gmli.bind.DatatypeConverter.printIntegerAsDatatypeN"/>
</jxb:baseType>
</jxb:property>
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="e7302" type="xs:integer" minOccurs="0">
<xs:annotation>
<xs:documentation>ActionCode</xs:documentation>
<xs:appinfo>
<jxb:property name="ActionCode">
<jxb:javadoc>7302 - ActionCode. </jxb:javadoc>
<jxb:baseType>
<jxb:javaType name="java.lang.Integer" parseMethod="com.citigroup.cdcla.gmli.bind.DatatypeConverter.parseIntegerFromDatatypeN" printMethod="com.citigroup.cdcla.gmli.bind.DatatypeConverter.printIntegerAsDatatypeN"/>
</jxb:baseType>
</jxb:property>
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="e40986" type="xs:string" minOccurs="0">
<xs:annotation>
<xs:documentation>ActionCodeDescription</xs:documentation>
<xs:appinfo>
<jxb:property name="ActionCodeDescription">
<jxb:javadoc>40986 - ActionCodeDescription. </jxb:javadoc>
</jxb:property>
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="e7928" type="xs:string" minOccurs="0">
<xs:annotation>
<xs:documentation>HostID</xs:documentation>
<xs:appinfo>
<jxb:property name="HostID">
<jxb:javadoc>7928 - HostID. </jxb:javadoc>
</jxb:property>
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="e8001" type="xs:integer" minOccurs="0">
<xs:annotation>
<xs:documentation>RetryFlag</xs:documentation>
<xs:appinfo>
<jxb:property name="RetryFlag">
<jxb:javadoc>8001 - RetryFlag. </jxb:javadoc>
<jxb:baseType>
<jxb:javaType name="java.lang.Integer" parseMethod="com.citigroup.cdcla.gmli.bind.DatatypeConverter.parseIntegerFromDatatypeN" printMethod="com.citigroup.cdcla.gmli.bind.DatatypeConverter.printIntegerAsDatatypeN"/>
</jxb:baseType>
</jxb:property>
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="e47602" type="xs:integer" minOccurs="0">
<xs:annotation>
<xs:documentation>CustomerTypeCode</xs:documentation>
<xs:appinfo>
<jxb:property name="CustomerTypeCode">
<jxb:javadoc>47602 - CustomerTypeCode. </jxb:javadoc>
</jxb:property>
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="e7504" type="SourceAccountIdentifier" maxOccurs="unbounded" minOccurs="0">
<xs:annotation>
<xs:documentation>SourceAccountIdentifierList</xs:documentation>
<xs:appinfo>
<jxb:property name="SourceAccountIdentifierList">
<jxb:javadoc>7504 - SourceAccountIdentifier Table. </jxb:javadoc>
</jxb:property>
<cdcla:elf group="true"/>
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:all>
</xs:complexType>
</xs:schema>

Below is the error that I am receiving Exception: src-resolve: Cannot resolve the name 'SourceAccountIdentifier' to a(n) 'type definition' component.

Also, I tried to remove SourceAccountIdentifier from my xsd definition, to see if it fails anywhere else, in that case, I recieve the below error

Exception: src\main\java\com\citi\cbol\test\MLIspec-1.6.dtd (The system cannot find the file specified)

Please help to provide some solution for the error. Thanks!!


Solution

  • The generated code is on github for you.

    I'm gussing that it's a problem with the xml or xsd files -- but I don't know for a fact.

    I removed the dtd for now, here's what I have so far:

    thufir@dur:~/xml/so$ 
    thufir@dur:~/xml/so$ ls
    foo.xml
    thufir@dur:~/xml/so$ 
    thufir@dur:~/xml/so$ cat foo.xml 
    <MLIspec> 
    <id>4050response</id> 
    <typename>4050Response</typename> 
    <description>Show the Contract Numbers</description>    
    <element> 
    <id>7504</id> 
    <name>SourceAccountIdentifier</name> 
    <type>table</type> 
    <required>true</required>       
    </element>
    </MLIspec>
    thufir@dur:~/xml/so$ 
    thufir@dur:~/xml/so$ trang foo.xml foo.xsd
    thufir@dur:~/xml/so$ 
    thufir@dur:~/xml/so$ cat foo.xsd 
    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
      <xs:element name="MLIspec">
        <xs:complexType>
          <xs:sequence>
            <xs:element ref="id"/>
            <xs:element ref="typename"/>
            <xs:element ref="description"/>
            <xs:element ref="element"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="typename" type="xs:NMTOKEN"/>
      <xs:element name="description" type="xs:string"/>
      <xs:element name="element">
        <xs:complexType>
          <xs:sequence>
            <xs:element ref="id"/>
            <xs:element ref="name"/>
            <xs:element ref="type"/>
            <xs:element ref="required"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="name" type="xs:NCName"/>
      <xs:element name="type" type="xs:NCName"/>
      <xs:element name="required" type="xs:boolean"/>
      <xs:element name="id" type="xs:NMTOKEN"/>
    </xs:schema>
    thufir@dur:~/xml/so$ 
    thufir@dur:~/xml/so$ xjc foo.xsd 
    parsing a schema...
    compiling a schema...
    generated/Element.java
    generated/MLIspec.java
    generated/ObjectFactory.java
    thufir@dur:~/xml/so$ 
    thufir@dur:~/xml/so$ tree
    .
    ├── foo.xml
    ├── foo.xsd
    └── generated
        ├── Element.java
        ├── MLIspec.java
        └── ObjectFactory.java
    
    1 directory, 5 files
    thufir@dur:~/xml/so$ 
    

    The tools are trang and xjc which install on Ubuntu Linux easily enough. Here's how to run the project, which builds from the console:

    thufir@dur:~/NetBeansProjects$ 
    thufir@dur:~/NetBeansProjects$ cat /home/thufir/xml/output.xml 
    cat: /home/thufir/xml/output.xml: No such file or directory
    thufir@dur:~/NetBeansProjects$ 
    thufir@dur:~/NetBeansProjects$ git clone git@github.com:THUFIR/xjc_generated-code.git
    Cloning into 'xjc_generated-code'...
    remote: Enumerating objects: 143, done.
    remote: Counting objects: 100% (143/143), done.
    remote: Compressing objects: 100% (81/81), done.
    remote: Total 143 (delta 25), reused 120 (delta 11), pack-reused 0
    Receiving objects: 100% (143/143), 79.43 KiB | 191.00 KiB/s, done.
    Resolving deltas: 100% (25/25), done.
    thufir@dur:~/NetBeansProjects$ 
    thufir@dur:~/NetBeansProjects$ cd xjc_generated-code/
    thufir@dur:~/NetBeansProjects/xjc_generated-code$ 
    thufir@dur:~/NetBeansProjects/xjc_generated-code$ gradle clean run
    
    > Task :run
    Jan 17, 2019 2:34:06 PM xjc_generated.code.driver.App unmarshallMLI
    INFO: generated.MLIspec@12edcd21
    
    BUILD SUCCESSFUL in 1s
    4 actionable tasks: 3 executed, 1 up-to-date
    thufir@dur:~/NetBeansProjects/xjc_generated-code$ 
    thufir@dur:~/NetBeansProjects/xjc_generated-code$ cat /home/thufir/xml/output.xml 
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <MLIspec>
        <id>4050response</id>
        <typename>4050Response</typename>
        <description>Show the Contract Numbers</description>
        <element>
            <id>7504</id>
            <name>SourceAccountIdentifier</name>
            <type>table</type>
            <required>true</required>
        </element>
    </MLIspec>
    thufir@dur:~/NetBeansProjects/xjc_generated-code$ 
    

    That should work even from Eclipse. Note that it's using gradle, or the Gradle Kotlin DSL for the build file, which Eclipse should be able to handle. Probably you want to import as a gradle project.

    You should only have to alter the properties.xml file for your system; the source code should be fine.