SAX parsing through a jar file declares XML document invalid

自古美人都是妖i 提交于 2020-01-05 08:00:50

问题


The picture is self explanatory. When I validate the document using identical process in CMD, the document is declared valid. It is valid when checked manually.

The jar file generates this message:

Invalid 
schema_reference.4: Failed to read schema document 'E:/XML and Java/Pro XML Development with Java/schema.xsd', because 
1) could not find the document; 
2) the document could not be read; 
3) the root element of the document is not <xsd:schema>.  

The question is: WHY?

The process of validating an XML using XSD via a JAR file is necessary for the application I am making.

SSCCE

package xml;

import javax.swing.*;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;

import javax.xml.parsers.*;

public class JarValidator extends JFrame{
    JTextArea area = new JTextArea();
    JScrollPane pane = new JScrollPane(area);
    SAXParserFactory factory;
    SAXParser parser;

    final String USER_DIR = System.getProperty("user.dir").replace('\\','/').concat("/");
    final String XML_FILE_NAME = "helloWorld.xml";
    final String SCHEMA_FILE_NAME = "schema.xsd";

    final String JAXP_SCHEMA_LANGUAGE_PROPERTY = 
            "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
    final String W3_SCHEMA_LANGUAGE = "http://www.w3.org/2001/XMLSchema";
    final String JAXP_SCHEMA_SOURCE_PROPERTY = "http://java.sun.com/xml/jaxp/properties/schemaSource";

    public JarValidator(){
        this.getContentPane().add(pane);
        this.pack();
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setVisible(true);

        try{
            factory = SAXParserFactory.newInstance();
            factory.setNamespaceAware(true);
            factory.setValidating(true);


            parser = factory.newSAXParser();
            parser.setProperty(JAXP_SCHEMA_LANGUAGE_PROPERTY, W3_SCHEMA_LANGUAGE);
            parser.setProperty(JAXP_SCHEMA_SOURCE_PROPERTY,
                    USER_DIR+SCHEMA_FILE_NAME);

            ErrorHandler handler = new ErrorHandler();
            parser.parse(new java.io.File(USER_DIR+XML_FILE_NAME), handler);

            if(handler.errorOccured == true){
                area.append("Invalid \n");
                area.append(handler.ex.getMessage());
            }else{
                area.append("Valid");
            }

        }catch(SAXException e){
            area.append(e.getMessage());
        }catch(ParserConfigurationException e){
            area.append(e.getMessage());
        }catch(java.io.IOException e){
            area.append(e.getMessage());
        }catch(Exception e){
            area.append(e.getMessage());
        }

    }

    private class ErrorHandler extends DefaultHandler{
        public SAXParseException ex = null;
        public boolean errorOccured = false;

        @Override
        public void error(SAXParseException ex) {
            this.ex = ex;
            errorOccured = true;
        }

        @Override 
        public void fatalError(SAXParseException ex){
            this.ex = ex;
            errorOccured = true;
        }

        @Override
        public void warning(SAXParseException ex){

        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            @Override public void run(){
                new JarValidator();
            }
        });
    }

}   

On a directory structure with no spaces in the name of any folders, the same error.

    Invalid 
    schema_reference.4: Failed to read schema document 'E:/test/schema.xsd', because 
1) could not find the document; 
2) the document could not be read;
3) the root element of the document is not <xsd:schema>.

Just thought I might add:
I am on a Windows 7 32 bit machine.
The JAR is in the same file as the XML and XSD hence user.dir works.


回答1:


In the Java XML world, a String parameter rarely (perhaps never) refers to a filename. Instead, it usually is expected to contain a URL. Given that, I would replace this code:

parser.setProperty(JAXP_SCHEMA_SOURCE_PROPERTY, USER_DIR+SCHEMA_FILE_NAME);

By this code (which also avoids the separator munging and string concatenation):

File userDir = new File(System.getProperty("user.dir"));
File schemaFile = new File(userDir, SCHEMA_FILE_NAME);
parser.setProperty(JAXP_SCHEMA_SOURCE_PROPERTY, schemaFile);

Two caveats:

  1. I simply typed this; it may contain typos.
  2. I did not take the time to check documentation for the property. However, it's how all the other JDK XML APIs work, so I feel confident that it's correct. Whatever documentation you're using to get the property name should give you more information.


来源:https://stackoverflow.com/questions/16615773/sax-parsing-through-a-jar-file-declares-xml-document-invalid

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!